javascript - 如何让 React HOC - 高阶组件协同工作?

标签 javascript reactjs

我有一个像这样的小演示组件:

function MyList({data, uppercaseMe, lowercaseMe}) {
    return <ul>
        {data.map(item =>
            <li>{item} -
                <button onClick={() => uppercaseMe(item)}>Uppercase me!</button>
                <button onClick={() => lowercaseMe(item)}>Lowercase me!</button>
            </li>)}
    </ul>;
}

然后我想用三个 HOC 来装饰 MyList:

const WithData = (Component) => {
return class extends React.Component {

    constructor(props) {
        super(props);
        this.state= {data:['one', 'two', 'three', 'four', 'five']};
    };

    render() {
        return <Component {...this.props} data={this.state.data} />;
    }
}
};

const WithUppercase = (Component) => {
return class extends React.Component {

    uppercaseMe = (item) => {
        // how to access WithData state from here?
        console.log(item.toUpperCase());
    };

    constructor(props) {
        super(props);
    };

    render() {
        return <Component {...this.props} uppercaseMe={this.uppercaseMe}/>;
    }
 }
};

const WithLowercase = (Component) => {
return class extends React.Component {

    lowercaseMe = (item) => {
        // how to access WithData state from here?
        console.log(item.toLowerCase());
    };

    constructor(props) {
        super(props);
    };

    render() {
        return <Component {...this.props} lowercaseMe={this.lowercaseMe}/>;
    }
 }
};

像这样:

const ComposedList = WithLowercase(WithUppercase(WithData(MyList)));

不幸的是,我不知道如何从 WithLowercase 或 WithUppercase 中更改 WithData 的状态。

如何将一个 HOC 的状态暴露给链中的另一个 HOCS?

最佳答案

您不想直接公开状态。您要做的是将一个函数作为 prop 传递给包装的组件,以允许您更新状态。

因此,如果我们采用 HOC 并添加一些代码,创建一个函数来更新其状态,现在可以将其传递给其子组件:

const WithData = (Component) => {
  return class extends React.Component {

      constructor(props) {
          super(props);
          this.state= {data:['one', 'two', 'three', 'four', 'five']};
      }

      update (data) {
        this.setState({ data });
      }

      render() {
          return <Component onUpdate={this.update} {...this.props} data={this.state.data} />;
      }
  }
};

现在我们可以在其中一个子组件中使用它:

const WithUppercase = (Component) => {
    return class extends React.Component {

        uppercaseMe = (item) => {
            const itemIndex = this.props.data.indexOf(item);
            const newData = this.props.data.slice();
            newData[itemIndex] = item.toUpperCase();
            this.props.onUpdate(newData); // update WithData state here
        };

        constructor(props) {
            super(props);
        };

        render() {
            // onUpdate function is once again passed to child components
            // implicitly through props if you need to call it again
            return <Component {...this.props} uppercaseMe={this.uppercaseMe}/>;
        }
    }
};

关于javascript - 如何让 React HOC - 高阶组件协同工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45515028/

相关文章:

javascript - 通过在模态外部单击来关闭模态

javascript - 控制组图例垂直居中但仅在静态创建时有效

javascript - 如何修复我的过滤器中的此 ESlint (no-param-reassign) 错误

reactjs - 采用 React-bootstrap 样式的 Formik

javascript - 如何在 JS 中循环对象数组并为每个对象获取网络数据?

javascript - 带有数组标签的 getElementById 或 getElementsByName

javascript - 相对于另一个物体旋转

javascript - 为什么这个CSS类条件在react js中不起作用?

reactjs - 如何向 React Bootstrap 轮播组件添加移动手势(例如触摸和滑动)?

reactjs - AWS Amplify React App 部署错误 - 重定向或 AWS build设置过多