2017-06-06 40 views
0

我有兩個響應組件,分別是ProgramSearchBox和DualBox,它們分別是預定義的npm包AutoSuggest和DualListBox的通用包裝組件。ReactJs redux:如果prop值改變,如何從渲染函數調用函數?

我的任務是基於ProgramSearchBox的值,我必須列出DualListBox中的設置值。

因此,如果用戶從ProgramSearchBox中選擇一個程序,那麼我將通過傳遞ProgramId並獲取結果值集並調用API,並且必須將它們綁定到DualListBox中。

我將從ProgramSearchBox中獲取用戶選擇的ProgramID作爲DualBox組件渲染方法中的一個道具。 如何通過傳遞ProgramId從DualBox組件中的渲染函數派發一個動作(調用一個函數)?

如果我在DualBox中調用render函數的方法,那就是變成無限循環!

這裏是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,那麼您的reducers應該有可能根據操作處理存儲中的更改,並且提供程序會將狀態已更改的組件 – 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

相關問題