小编典典

反应反模式?

reactjs

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

// componentA.js



function bleedContext() {

  ComponentA.staticMethod = ComponentA.staticMethod.bind(this)

}



export default class ComponentA {

  static staticMethod() {

    this.setState({foo: 'bar'})

  }



  constructor() {

    this.state = {}

    bleedContext.call(this)

  }



  render() {

    return (

      ...

    )

  }

}



// componentB.js



import ComponentA from 'path/to/componentA'



export default class ComponentB {

  handleClick() {

    ComponentA.staticMethod()

  }



  render() {

    return (

      <button onClick={this.handleClick} />

    )

  }

}

阅读 212

收藏
2020-07-22

共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可以通过context 使用with 和close方法:

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

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

这是一个演示

2020-07-22