React - 与子组件交互

时间:2017-06-29 15:33:03

标签: reactjs oop typescript encapsulation

我想知道亲子组件互动的最佳做法是什么,以及以下方法是否满足良好做法。

假设我们有两个组件:ParentChild,其中Parent以类似于获取ref on元素的方式获取Child上的处理程序。

class Parent extends React.Component<{}, {}> {

  private handlers: {
    Child: ChildHandlers
    /** And so on... **/
  };

  render() {
    return (
      <div>
        <Child handlers={(handlers: ChildHandlers) => { this.handlers.Child = handlers; }} />
        <button onClick={() => this.handlers.Child.toggle() /** Or change Parent.state and then trigger **/}>toggle from parent</button>
      </div>
    );
  }
}

class Child extends React.Component<ChildProps, ChildState> {
  constructor(props: ChildProps) {
    super(props);

    this.exposeHandlers();
  }

  private toggle(): void {
    this.setState({ visible: !this.state.visible });
  }

  private exposeHandlers() {
    let handlers: ChildHandlers = {
      toggle: () => this.toggle()
    };

    this.props.handlers(handlers);
  }

  render() {
    return (
      <div>
        { this.state.visible && (
          <div>
            <h2>I'm being toggled!</h2>
            <button onClick={() => this.toggle()} />toggle from child<button>
          </div>
        ) }
      </div>
    );
  }
}

似乎很好,因为:

  • 它可以保持一致
  • 这就像暴露两个组件使用的接口而不会过多地耦合它们
  • 在合理范围内保持儿童的国家不受父母的影响
  • 在更新Child状态后,更容易添加回调到toggle方法以对Parent执行某些操作。

但由于我没有经验,有没有(甚至是最轻微的)问题?

1 个答案:

答案 0 :(得分:0)

对我来说似乎太过分了。

公开这些方法并在Parent中引用Child的实例然后在需要时调用这些方法有什么不对?

父:

class Parent extends React.Component<{}, {}> {
    private child: Child;

    render() {
        return (
            <div>
            <Child ref={ el => this.child = el } />
            <button onClick={() => this.child.toggle()}>toggle from parent</button>
            </div>
        );
    }
}

子:

class Child extends React.Component<{}, ChildState> {
    public toggle(): void {
        this.setState({ visible: !this.state.visible });
    }

    render() {
        if (!this.state.visible) {
            return <div />;
        }

        return (
            <div>
                <div>
                    <h2>I'm being toggled!</h2>
                    <button onClick={() => this.toggle()}>toggle from child</button>
                </div>
            </div>
        );
    }
}