2017-06-06 19 views
0

私はProgramSearchBoxとDualBoxという2つの反応コンポーネントを持っています。これらは、それぞれ定義済みのnpmパッケージAutoSuggestとDualListBoxの包括的でラッパーコンポーネントです。ReactJs redux:prop値が変更された場合にレンダリング関数から関数を呼び出す方法は?

達成するべき課題は、ProgramSearchBoxの値に基づいて、DualListBoxに設定された値をリストする必要があります。

ProgramSearchBoxからProgramを選択すると、ProgramIdを渡してAPIを呼び出し、結果の値のセットをフェッチしてDualListBoxにバインドする必要があります。

DualBoxコンポーネントのレンダリング方法で、ProgramSearchBoxからユーザーが選択したProgramIDを小道具として取得します。 ProgramIdを渡してDualBoxコンポーネントのレンダリング機能からアクション(関数を呼び出す)をディスパッチする方法は?

デュアルボックスのレンダー機能からメソッドを呼び出すと、無限ループになります!ここで

はDualBoxコンポーネントである:ここで

//DualBox.js 
    class DualBox extends React.Component { 
     constructor() { 
     super(); 

     this.state = { selected: [] }; 

     this.onChange = this.onChange.bind(this); 

     this.options = [ ]; 

     } 

     onChange(selected) { 
     selected(selected); 

     } 

     updateOptions() 
     { 
     console.log("Update Option method called :" + this.props.traineesList); 
     this.options = [{ value: 'luna', label: 'Moon' }, { value: 'phobos', label: 'Phobos' }]; 
     //this.options = this.props.traineeList.map((value,id) =>) 
     } 
     render() { 


      const {ProgramID} = this.props; // HERE I GET ProgramID AS PROP FROM AN ANOTHER COMPONENT 
      const {selected} = this.state; 

      if(ProgramID !== "") // BASED ON THIS ProgramID VALUE, I NEED TO DISPATCH AN ACTION. 
      { 
       {this.updateProgramId(ProgramID)} // THIS IS CAUSING INFINITE LOOP 
       {this.updateOptions} 
      console.log("Program Id came to dualbox:" +ProgramID); 
     return <DualListBox options={this.options} selected={selected} onChange={this.onChange} 
      canFilter 
       filterCallback={(option, filterInput) => { 
        if (filterInput === '') { 
         return true; 
        } 

        return (new RegExp(filterInput, 'i')).test(option.label); 
       }} 
       filterPlaceholder="Filter..." 
      />; 
      } 
      else 
      { 
      console.log("Program Id didn't come to dualbox"); 
     return <DualListBox options={this.options} selected={selected} onChange={this.onChange} 
      canFilter 
       filterCallback={(option, filterInput) => { 
        if (filterInput === '') { 
         return true; 
        } 

        return (new RegExp(filterInput, 'i')).test(option.label); 
       }} 
       filterPlaceholder="Filter..." 
      />; 
      } 

     } 
    } 

    function mapStateToProps(state, ownProps) { 
     return { 
     traineesList: state.traineesList 
     }; 
    } 

    const mapDispatchToProps = (dispatch, ownProps) => { 

     return { 
     updateProgramId: bindActionCreators(({ProgramID}) => dualBoxActions.getTraineesList(ProgramID), dispatch) 
     }; 
    } 


    export default connect(mapStateToProps,mapDispatchToProps)(DualBox); 

はProgramSearchBoxコンポーネントです:

function renderSuggestion(suggestion) { 
     return (
     <ul> 
      <li>{suggestion.Program}</li> 
     </ul> 

    ); 
    } 

    class ProgramSearchBox extends React.Component { 
     constructor(props) { 
     super(props); 


     } 


     render() { 
     const { value, suggestions, onChange, onSuggestionSelected} = this.props; 

     const inputProps = { 
      placeholder: "Look Up", 
      value, 
      onChange: (event, { newValue, method }) => { 
       this.setState({ 
       value: newValue 
       }); 
       console.log("onChange: " + JSON.stringify(newValue)); 
       onChange(newValue); 

      } 

     }; 

     return (
      <Autosuggest 
      suggestions={suggestions} 
      onSuggestionsFetchRequested={this.props.onSuggestionsFetchRequested} 
      onSuggestionsClearRequested={this.props.onSuggestionsClearRequested} 
      onSuggestionSelected={ 
       (event, { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }) => { 

       console.log("onSuggestionSelected: " + JSON.stringify(suggestion)); 
       onSuggestionSelected(suggestion); 

       } 
      } 
      getSuggestionValue={(suggestion) => suggestion.Program} 
      renderSuggestion={renderSuggestion} 
      inputProps={inputProps} 
      theme={theme} 
      /> 
     ); 
     } 
    } 



    function mapStateToProps(state, ownProps) { 
     return { 
     suggestions: state.results 
     }; 
    } 
    const mapDispatchToProps = (dispatch, ownProps) => { 

     return { 

     onSuggestionsFetchRequested: bindActionCreators(({ value }) => searchActions.getProgramSuggestions(value), dispatch), 
     onSuggestionsClearRequested: bindActionCreators(() => searchActions.clearSuggestions(), dispatch), 

     }; 
    } 


    export default connect(mapStateToProps, mapDispatchToProps)(ProgramSearchBox); 
+0

がこれまでにレンダリング機能から派遣ことはありませんが、それは新しいが、レンダリングcomponentDidMountまたはいくつかの類似のライフサイクルメソッドのいずれかを使用する原因となります。 reduxを正しく使用している場合、レデューサーはアクションに基づいて店舗の変更を処理できる可能性があり、プロバイダーは状態が変更されたコンポーネントを再レンダリングします – Icepickle

答えて

2

render()方法で他の関数を呼び出さないでください。レンダリングメソッドはレンダリングビューの責任しか持たず、何回も呼び出すことができ、可能な限り純粋でなければなりません。

小道具の変更に応じてアクションを実行するには、componentWillReceiveProps(nextProps)ライフサイクル機能を使用してください。

それはこのようになります:

componentWillReceiveProps(nextProps) { 
    if (nextProps.ProgramID !== '' && this.props.ProgramID !== nextProps.ProgramID) { 
     this.updateProgramId(ProgramID) 
    } 
} 

更新し、メソッドが呼び出されますレンダリングされますthis.updateProgramId(ProgramID)小道具を呼び出した後。 ReactJSのライフサイクルについて

さらに詳しい情報: https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

関連する問題