我有两个反应组件是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);
答案 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