2015-09-06 150 views
0

我實際上正在學習reactjs,而我實際上正在開發一個包含在名爲TODO的「父組件」內的小T​​ODO列表。Reactjs,父組件,狀態和道具

在這個父類的內部,我想從關注的存儲中獲取TODO的當前狀態,然後將此狀態作爲屬性傳遞給子組件。

問題是,我不知道在哪裏初始化我的父狀態值。其實,我使用ES6語法,所以我沒有getInitialState()函數。它寫在文檔中,我應該使用組件構造函數來初始化這些狀態值。

事實是,如果我想初始化我的構造函數內部的狀態,this.context(Fluxible Context)實際上是未定義的。

我決定移動componentDidMount中的初始化,但它似乎是反模式,我需要另一種解決方案。你可以幫我嗎 ?

這裏是我的實際代碼:

import React from 'react'; 
import TodoTable from './TodoTable'; 
import ListStore from '../stores/ListStore'; 

class Todo extends React.Component { 

    constructor(props){ 
    super(props); 
    this.state = {listItem:[]}; 
    this._onStoreChange = this._onStoreChange.bind(this); 
    } 

    static contextTypes = { 
     executeAction: React.PropTypes.func.isRequired, 
     getStore: React.PropTypes.func.isRequired 
    }; 

    componentDidMount() { 
     this.setState(this.getStoreState()); // this is what I need to move inside of the constructor 
     this.context.getStore(ListStore).addChangeListener(this._onStoreChange); 
    } 

    componentWillUnmount() { 
     this.context.getStore(ListStore).removeChangeListener(this._onStoreChange); 
    } 

    _onStoreChange() { 
    this.setState(this.getStoreState()); 
} 

    getStoreState() { 
     return { 
      listItem: this.context.getStore(ListStore).getItems() // gives undefined 
     } 
    } 

    add(e){ 
    this.context.executeAction(function (actionContext, payload, done) { 
     actionContext.dispatch('ADD_ITEM', {name:'toto', key:new Date().getTime()}); 
    }); 
    } 


    render() { 
    return (
     <div> 
     <button className='waves-effect waves-light btn' onClick={this.add.bind(this)}>Add</button> 
     <TodoTable listItems={this.state.listItem}></TodoTable> 
     </div> 
    ); 
    } 
} 


export default Todo; 
+0

我很好奇,你在哪裏讀到,在componentDidMount方法中獲取或設置'state'是一個_anti-pattern_? –

+0

@TahirAhmed,在這裏:https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html –

+0

hmm但它在那篇文章中提到了'componentDidMount'?我的意思是我在我的項目中所做的幾乎與你正在做的一樣,即在'componentDidMount'函數內使用'this.setState(...)',直到現在,我認爲使用它就好了。我現在很好奇別人怎麼看,因爲我個人認爲沒有任何問題。 –

回答

1

正如你應該從Fluxible addons受益變化無常的用戶:

以下示例將偵聽FooStore和BarStore中的更改,並在實例化時將foo和bar作爲道具傳遞給Component。

class Component extends React.Component { 
    render() { 
     return (
      <ul> 
       <li>{this.props.foo}</li> 
       <li>{this.props.bar}</li> 
      </ul> 
     ); 
    } 
} 

Component = connectToStores(Component, [FooStore, BarStore], (context, props) => ({ 
    foo: context.getStore(FooStore).getFoo(), 
    bar: context.getStore(BarStore).getBar() 
})); 

export default Component; 

查看fluxible example瞭解更多詳情。代碼exсerpt:

var connectToStores = require('fluxible-addons-react/connectToStores'); 
var TodoStore = require('../stores/TodoStore'); 
... 

TodoApp = connectToStores(TodoApp, [TodoStore], function (context, props) { 
    return { 
     items: context.getStore(TodoStore).getAll() 
    }; 
}); 

因爲你不會需要調用的setState結果,所有的存儲數據將在組件的道具。

+0

我想知道是否有可能使我們的反應組件中的通量分離?你認爲創建reactjs組件,導出它們,以及在另一個文件中導入時,我們是否將它裝飾到另一個文件中是一個好主意?因此,我們的reactjs組件可以很容易地導出,裝飾僅在通量項目 – mfrachet

+0

中閱讀本文https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0。你應該保持轉儲組件不知道通量(它們只能在道具和自己的狀態下運行),只有頂級智能組件纔會有一些邏輯來與流通商店集成 –

+0

所以我的解決方案似乎是一件好事,即使對於父組件也沒有? – mfrachet