【问题标题】:React-JS: Access a child's method through HOC wrapperReact-JS:通过 HOC 包装器访问子方法
【发布时间】:2016-06-27 20:39:26
【问题描述】:

我有一个看起来像这样的Editor 组件:

class EditorComp extends Component {
  focus() {
    this.refs.input.focus();
  }

  render() {
    return (
      <input 
        ref="input"
        ...
      />
    );
  }
}

因此使用EditorComp 的元素可以设置一个引用并调用其focus 方法并将焦点应用于较低级别的输入,如下所示:

class Parent extends Component {
  render() {
    return (
      <div>
        <button onClick={() => this.refs.editor.focus()}>Focus</button>
        <EditorComp ref="editor" />
      </div>
    );
  }
}

但是,当将 EditorComp 包装在高阶组件中(如 react-reduxconnect())时,EditorComp 会失去焦点方法,因为它被困在 HOC 之下。

例子:

const WrappedEditor = connect()(EditorComp); // react-redux's connect, for example
const wrappedEditorInstance = <WrappedEditor />;

wrappedEditorInstance.focus() // Error! Focus is not a function.

有没有办法通过子组件的父 HOC 传递方法或组件引用?


编辑:或者是否有相反的解决方案,其中父母传递一个设置焦点命令的功能?我考虑过使用event-emitter,并让孩子听由父母调用的focus 事件,但这似乎笨拙且不必要。

【问题讨论】:

    标签: javascript reactjs redux react-redux


    【解决方案1】:

    1路返回comp实例

    class EditorComp extends Component {
      focus() {
        this.refs.input.focus();
      }
      componentDidMount(){
        this.props.onMount(this)
      }
      render() {
        return (
          <input
            ref="input"
            ...
          />
        );
      }
    }
    export default connect(state=>({state}), actions)(EditorComp);
    
    
    class Parent extends Component {
      render() {
        return (
          <div>
            <button onClick={() => this.editor.focus()}>Focus</button>
            <EditorComp  onMount={c=>this.editor=c}  ref="editor" />
          </div>
        );
      }
    }
    

    2路下传位置

    class EditorComp extends Component {
      componentDidUpdate(prevProps, prevState){
        let {input}= this.refs
        this.props.isFocus? input.focus():input.blur();
      }
      render() {
        return (
          <input
            ref="input"
            ...
          />
        );
      }
    }
    export default connect(state=>({state}), actions)(EditorComp);
    
    
    class Parent extends Component {
      render() {
        return (
          <div>
            <button onClick={() => this.setState({isfocus:true});}>Focus</button>
            <EditorComp  isFocus={this.state.isfocus}  ref="editor" />
          </div>
        );
      }
    }
    

    【讨论】:

    • 感谢您的回答! 1 way return comp instance 接近完美,但看起来2 way pass down position 可能无法按预期工作。只要this.props.isfocus === true 更新,EditorComp 就会尝试窃取焦点。这可能可以处理,但应该注意。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 2019-12-28
    • 2021-04-12
    • 2017-07-11
    • 1970-01-01
    相关资源
    最近更新 更多