【问题标题】:React: Higher Order Components: Can you can childs state反应:高阶组件:你可以孩子状态吗
【发布时间】:2017-04-01 22:47:47
【问题描述】:

我正在尝试从 mixins 重构为 HOC,以便我可以升级到最新的 React(我目前使用的是 React 13/ES5)。当我的组件加载时,mixin 能够访问一个数据对象this.data,它有一个带有路由的query 属性。

React.createClass({
  mixins: [myMixin],
  data: {
    query: "/api/foo"
  },
  componentDidUpdate(): function(){
  }
  ...
}

componentDidMount 在 mixin 中,它会查询该路由,取回数据并将其置于状态。

var myMixin = React.createClass({
  componentDidMount(): function(){
    this.fetchData(this.data.query)
  }
  fetchData(query) {
    // fetch the data
  }
  ...
}

这会从我的组件中提取大量样板文件。我不必在每个组件上都运行componentDidMount,只需使用data 对象即可。

我把这个 mixin 分散在整个项目中。它实际上做的远不止这些,但我只是想把它简化一下。

出现了 HOC。我从data 中取出所有东西并放入getInitialState。现在我在现在包装的组件状态上有data,我该如何访问它?像我的 mixin 一样,我希望我的 HOC 处理我的 componentDidMount,访问 data.query 并获取数据。我不想为了拥有componentDidMount 而重写每个组件。

PS- 我通常使用最新版本的 React 和 ES6,如果有人能告诉我为什么 mixin 可以做 this.data 而我的组件不能,那将非常有帮助。在最新版本的 React 中,你不能像这样在 render() 之外定义对象。

【问题讨论】:

  • 如果您愿意发布您的 HoC 代码,回答这个问题会更容易
  • 我不同意。如果你不能在最基本的层面上回答这个问题,你怎么能以更复杂的方式回答这个问题
  • 这不是很好。由于您编写它的方式,您的问题相当难以理解。我花时间阅读它,并试图提出一个适合您的解决方案。如果您想要一个模糊的答案:您可以使用子组件需要与父组件通信的任何标准模式。通过道具将东西传递给孩子(您可以将包装器的状态作为道具传递给孩子)。如果您的孩子需要与父母沟通,请让父母向其传递一个处理函数。
  • 要么改写你的问题,以便更清楚你想要了解什么,要么发布一些高阶组件的伪代码,以便我提供更好的答案。

标签: reactjs mixins ecmascript-5 higher-order-components


【解决方案1】:

React 不鼓励从组件外部更改 statestate 归组件所有,因此只有组件可以控制它。

来自React documentation

State 类似于 props,但它是私有的,完全由 组件。

所以你可以做的是使用props 而不是state。对于给定的示例,您可以编写高阶组件,如下所示。但是您的 Child 组件应该被更改为从 props 而不是 state 呈现数据。

function HOC(WrappedComponent){

  return React.createClass({

    getInitialState: function() {
      return { data: null };
    },

    componentDidMount: function(){
      this.fetchData(WrappedComponent.prototype.data.query)
    },

    fetchData: function(query){
     // Fetching data first
     // Then set the state with data
     this.setState({data:data});
    },

    render: function() {
      var props = Object.assign({}, this.props, this.state);
      return React.createElement(WrappedComponent, props);
    }

  });

}

var HOCChild = HOC(Child);

PS- 我通常使用最新版本的 React 和 ES6,如果有人可以的话 告诉我为什么 mixin 可以做到 this.data 而我的组件不能 这将非常有帮助。在最新版本的 React 中你不能 像这样在 render() 之外定义一个对象。

通常,React 组件定义为 ES6 类。 ES6 类不支持静态或实例属性。但是您可以像这样在承包商内部定义实例属性。

class A{
  constructor(){
    this.foo = "foo"
  }
}

【讨论】:

    猜你喜欢
    • 2017-10-18
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    相关资源
    最近更新 更多