反映反模式? [英] React anti pattern?

查看:65
本文介绍了反映反模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is the following an anti pattern in React? I like the pattern because it gives me context in static functions when a component has been instantiated. Then later I can import the class and call a static method to modify state. Or can this be done in a better way?

// 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} />
    )
  }
}

推荐答案

这显然是反模式,可能是一个错误,具体取决于条件。静态类方法不应该与类实例一起操作。 staticMethod 绑定到特定组件实例并使用 setState ,这可能只是证明一个类是单例(尽管是单身通常也是反模式。如果预期有多个类实例,这将导致错误和内存泄漏,并且每个React组件都应该有多个实例,至少是为了测试。

This is clearly an antipattern and possibly a mistake, depending on conditions. Static class method shouldn't operate with class instance. staticMethod is bound to specific component instance and uses setState, this could be only justified a class is a singleton (though a singleton is often an antipattern, too). This will result in bugs and memory leaks if more than one class instance is expected, and every React component is expected to have more than one instance, at least for testing.

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

A proper way for two independent components to interact with each other in React is to have a common parent component that provides this interaction, e.g.:

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

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

以上示例的问题是这需要如果< SomeComponentThatUsesModal> 嵌套,则传递 modalRef 支持。

The problem with example above is that this will require to pass modalRef prop deeply if <SomeComponentThatUsesModal> is nested.

使用React上下文或其他第三方全局状态解决方案(如Redux)解决了此问题。

This problem is solved with React context or other third-party global state solutions like Redux.

这可以使用React 16.3上下文API完成,考虑到模态类实例有打开方法:

This can be done with React 16.3 context API, considering that Modal class instance has open method:

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 并且将通过上下文提供关闭方法:

Then for any deeply nested component modal object with open and close methods will be available via context:

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

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

这是演示

这篇关于反映反模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆