反应反模式?

时间:2018-09-11 12:55:02

标签: javascript reactjs static

以下是React中的反模式吗?我喜欢这种模式,因为当实例化一个组件时,它在静态函数中为我提供了上下文。然后,我可以导入该类并调用静态方法来修改状态。还是可以通过更好的方式做到这一点?

<= -1

1 个答案:

答案 0 :(得分:1)

根据情况,这显然是一种反模式,并且可能是一个错误。静态类方法不应与类实例一起使用。 staticMethod绑定到特定的组件实例并使用setState,这只能证明类是单例是合理的(尽管单例也经常是反模式)。如果期望一个以上的类实例,并且至少在测试中,每个React组件都应该有一个以上的实例,这将导致错误和内存泄漏。

React中两个独立组件相互交互的正确方法是拥有一个提供这种交互的公共父组件,例如:

class ModalContainer extends Component {
  modalRef = React.createRef();

  render() {
    return <>
      <Modal ref={this.modalRef} />
      <SomeComponentThatUsesModal modalRef={this.modalRef} />
    </>;
  }
}

上述示例的问题在于,如果嵌套modalRef,则需要深入传递<SomeComponentThatUsesModal>属性。

此问题可以通过React上下文或其他第三方全局状态解决方案(例如Redux)解决。

考虑到Modal类实例具有open方法,可以使用React 16.3上下文API进行此操作:

const ModalContext = React.createContext();

function getModal(modalRef) {
  return {
    open: data => modalRef.current.open(data);
    close: () => modalRef.current.close();
  }
}

class ModalContainer extends Component {
  modalRef = React.createRef();

  render() {
    return <>
      <Modal ref={this.modalRef} />
      <ModalContext.Provider value={getModal(this.modalRef)}>
        {this.props.children}
      </ModalContext.Provider>
    </>;
  }
}

然后对于任何带有open和close方法的深度嵌套组件模态对象,都可以通过上下文使用:

const SomeComponentThatUsesModal = props => <div>
  <ModalContext.Consumer>
    {modal => <button onClick={() => modal.open('foo')} />}
  </ModalContext.Consumer>
</div>;

<ModalContainer>
  ...deeply nested component
  <SomeComponentThatUsesModal />
  ...
</ModalContainer>

这里是demo