2017-02-06 8 views
0

次のケースでデータ/レデックスストアを整理する最良の方法を見つける問題があります。Reactでの設計:reduxストアを使用して、子コンポーネントから親コンポーネントへデータを伝播しないでください。

ユーザーのリストを表示するテーブルを表示したいとします。表の上には、他の機能の中には「フィルタ」フォーム(検索テキストに基づいてユーザーのリストをフィルタリングできるようにする)を含むTableHelperコンポーネントがあります。

以下のコードでは、データ配列を小道具とし、要素ごとに1つの行を表示するTableコンポーネントがあります。 テーブルヘルパーコンポーネントは、データソース(すべてのユーザ)を取り、それが検索テキストに基づくフィルタ、及び店舗で得フィルタリングされたリストを格納する、store.tableHelper.data

テーブルとして、他方で、フィルタリングされたデータをレンダリングフィルタが適用されていない場合は、データ全体をレンダリングするだけです。

このアプローチには多くの欠陥があります。これは、テーブルヘルパーコンポーネントをアプリケーション間で、または同じページ上で複数のテーブルで使用できるためです。実際には、フィルタリングされたリストをストアから完全に保持する方が望ましいでしょう。フィルタリングされたリストはTableHelperコンポーネント内で計算され、フィルタリングされたリストをテーブルに供給する親コンテナ(コードは下にある)に返される必要があります。

この場合、店舗の使用をバイパスすることができますか?いっそ、何がこの問題のためのソリューションを設計するためのより良いアプローチ、与えられた次の制約次のようになります。

  • より良い再利用性のために、独自のコンポーネントとしてTableHelperを保つ濾過しストアを汚染
  • 回避各テーブルに一覧表示

コード:

@connect((store) => { 
    return { 
    users: store.user.users, 
    filteredData: store.tableHelper.data 
    } 
}) 
export default class Users extends React.Component { 

    componentDidMount() { 
    this.props.dispatch(user.getAllUsers()); 
    } 

    render() { 
    const sourceData = _.map(this.props.users, function(user, i) { 
     return { 
     'name': user.fullName, 
     'email' : user.email, 
     'key': i 
     } 
    }) 

    // tableData shows the filtered data if such data is defined 
    // otherwise, tableData is the source data 
    let tableData = this.props.filteredData; 

    if (!this.props.filteredData) { 
     tableData = sourceData; 
    } 

    return (
     <div> 
     <TableHelper data={sourceData}/> 
     <Table tableData={tableData} /> 
     </div> 
    ) 
    } 
} 

どうもありがとう

答えて

1

子へのコールバックを小道具として渡すことができます。その後、TableHelperコンポーネントでフィルタリングされたデータが準備できたら、そのコールバックに情報を渡すことができます。代わりにあなたのTableHelperコンポーネントでReduxのストアを更新する、

@connect((store) => { 
    return { 
    users: store.user.users 
    } 
}) 
export default class Users extends React.Component { 

    componentDidMount() { 
    this.props.dispatch(user.getAllUsers()); 
    } 

    // Callback that will be passed to the TableHelper component. 
    handleFiltered = (data) => { 
    this.setState({ 
     filteredData: data 
    }); 
    } 

    render() { 
    const sourceData = _.map(this.props.users, function(user, i) { 
     return { 
     'name': user.fullName, 
     'email' : user.email, 
     'key': i 
     } 
    }) 

    // tableData shows the filtered data if such data is defined 
    // otherwise, tableData is the source data 
    tableData = this.state.filtered ? this.state.filtered : sourceData; 

    return (
     <div> 
     <TableHelper data={sourceData} updateFiltered={this.handleFiltered} /> 
     <Table tableData={tableData} /> 
     </div> 
    ) 
    } 
} 

その方法、:あなたはフィルタリングされたデータを渡すとき、それは何かのように、自動的に更新されますので、あなたはおそらく、あなたの親コンポーネント内部のコンポーネントの状態としてそれを持っていることになるでしょうコールバックを使用してデータをその親に戻します。

+0

ありがとうございます、これははるかにクリーンです! – Khorkhe

関連する問題