ReactJs redux:如果prop值改变,如何从render函数调用一个函数?

时间:2017-06-06 08:36:51

标签: reactjs redux react-redux

我有两个反应组件是ProgramSearchBox和DualBox,它们分别是预定义的npm包AutoSuggest和DualListBox的通用和包装组件。

我要完成的任务是基于ProgramSearchBox的值,我必须列出DualListBox中的设置值。

因此,如果用户从ProgramSearchBox中选择一个程序,那么我将通过传递ProgramId来调用API并获取结果值集,并且必须将它们绑定在DualListBox中。

我将从ProgramSearchBox中将用户选择的ProgramID作为DualBox组件渲染方法中的prop。 如何通过传递ProgramId来从DualBox组件中的render函数调度一个动作(调用一个函数)?

如果我在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);

1 个答案:

答案 0 :(得分:3)

请勿使用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