首页 > 解决方案 > 高阶组件

问题描述

A/t to Docs,HOC 不修改输入组件,也不使用继承来复制其行为。相反,HOC 通过将原始组件包装在容器组件中来组成原始组件。

在反应中,如果 props 发生变化,组件将使用 newProps 重新渲染。

由于在 HOC 中,我们将 props 传递给包装器组件 test1 和 test2,因此它们都应该在每次 props 更改时重新渲染。但这并没有发生。事实上,test1 和 test2 被渲染然后 test2 通过状态提升和重新渲染来改变道具。但 test1 保持不变。检查附加的图像。

我很想知道 react-redux connect 和 react-router-dom withRouter 是如何在每个 props 更改上实际工作的,以存储和重新渲染组件。

Github 上的真正问题

class Test extends React.Component {
  render() {
    return (
      <div>
        <Test1 />
        <Test2 />
      </div>
    )
  }
}

具有 HOC 的组件

class Test1 extends React.Component {
  render() {
    return(
      <div>
          {
              this.props.test1
          }
          {
              this.props.test2
          }
      </div>
     )
  }
}
export default withHOC(Test1);

另一个具有 HOC 的组件

class Test2 extends React.Component {
  render() {
    return(
      <div>
        {
            this.props.test1
        }
        {
            this.props.test2
        }
        <button type='button' onClick={()=>this.props.update('test')}>Update </button>
      </div>
    )
  }
}
export default withHOC(Test2);

高阶组件

function withHOC(WrappedComponent) {
  class Test extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
          test1: 'test1',
          test2: 'test2'
      }
    }
    update = (u) => {
      this.setState({
          test2: u 
      })
    }
    render() {
      const test1 = this.state.test1;
      const test2 = this.state.test2;
      return (<WrappedComponent test1={test1} test2={test2} update={this.update}/>);
    }
  }
  return Test;
}
export default withHOC;

生命周期方法日志

标签: reactjsreact-reduxreact-router-dom

解决方案


首先,你没有在这里真正提出一个问题——这篇文章的标题应该被重写,以便真正提出一些问题。

我是否正确地说您正在尝试使用 HOC 在两个组件之间共享状态?然后期待更新<Test2 />导致更新<Test1 />,因为props.test2on<Test2 />已经改变?

如果是这样,那么这就是思考 HOC 的错误方式。将 HOC 视为具有特定属性或行为的装饰组件。在您的问题中使用withHOCdetail 并不是说​​“让任何包含withHOC在此 HOC 中定义的组件访问单个状态”,而是说“任何包含在其中的组件withHOC都应具有由此 HOC 中给出的函数定义的自己的状态” .

所以包装两个组件,然后<Test2 />改变状态,只会改变那个特定组件的状态。

如果您希望更新 in<Test2 />导致更新<Test1 />,则必须使用父组件的状态(即<Test />)来完成。


推荐阅读