2017-04-01 97 views
1

我想重构mixin到HOC,所以我可以升级到最新的反应(我目前使用React 13/ES5)。当我的组件加载时,mixin可以访问数据对象this.data,该数据对象具有query属性和路由。反应:高阶组件:你可以孩子状态

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

componentDidMount的混入里面,它会询问这条路线,取回数据,并把它的状态。

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

这从我的组件提取了很多样板。我不必在每个组件上运行componentDidMount,只需要有data对象。

我把这个mixin分散在整个项目中。它实际上做的比这更多,但我只是试图让它失望。

进来HOCs。我把所有的东西从data拿到getInitialState。现在,我在现在包装的组件的状态上有data,我该如何访问它?就像我的mixin,我希望我的HOC能够处理我的componentDidMount,访问data.query并获取数据。我不想重写每个组件都有componentDidMount

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

+0

回答这个会更容易,如果你愿意发布你的HoC代码 –

+0

我不同意。如果你不能在最基本的层面回答这个问题,你应该如何回答它,并增加复杂性。 – user2465134

+0

这不太好。由于您的写作方式,您的问题相当难以理解。我花时间阅读并试图为您量身定制解决方案。如果您想要一个模糊的答案:您可以使用任何标准模式,其中子组件需要与父组件进行通信。通过道具把东西传递给孩子(你可以把你的包装的状态作为道具传递给孩子)。如果您的孩子需要回传给父母,请让父母将其传递给处理函数。 –

回答

1

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

React documentation

状态类似于道具,但它是私有的,由 组件完全控制。

所以你可以做的是使用props而不是state。对于给定的示例,您可以按如下所示编写高阶组件。但是您的子组件应该被更改为呈现来自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-我通常使用的反应,ES6,如果任何人都可以 告诉我为什么混入可以做this.data和我的组件不能 那将是非常有益的最新版本。在最新版本的React中,您不能在像这样的render()之外定义一个对象。

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

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