React Native:'componentWillReceiveProps'清除下拉列表选定值

时间:2018-04-04 19:38:12

标签: javascript reactjs react-native

我使用React Native Modal Dropdown插件创建了一个由两个下拉列表字段(以及其他表单元素)组成的表单。两个下拉列表是:

  1. 国家/地区列表
  2. 州名单(按上面选择的国家/地区筛选)
  3. 我目前遇到状态下拉列表的问题,它从状态下拉列表中选择项目时设置的状态中收到countryId值。然后用它来传递给我的State Drop Down。

    值得注意的是,我上面列出的两个下拉列表已经分离成可重用的组件。

    表格代码:

    static propTypes = {
        navigation: PropTypes.object
    };
    
    state = {
        countryId: 0,
        stateId: 0
    }
    
    componentWillMount() {
    }
    
    onCountryDropDownSelected = (val) => {
        this.setState({ countryId: val });
    }
    
    onStateDropDownSelected = (val) => {
        this.setState({ stateId: val });
    }
    
    render() {
        return (
            <Container>
                <StatusBar barStyle="default" />
                <CountryDropDownList onSelect={this.onCountryDropDownSelected} />
                <Text>Country: {this.state.countryId}</Text>
                <StateDropDownList onSelect={this.onStateDropDownSelected} countryId={this.state.countryId} />
            </Container>
        );
    }
    

    StateDropDownList组件的代码:

    class StateDropDownList extends Component {
        static propTypes = {
            countryId: PropTypes.number,
            onSelect: PropTypes.func
        };
    
        state = {
            data: [],
            errorMessage: '',
            isLoading: false
        }
    
        componentWillReceiveProps(nextProps) {
            if (nextProps.countryId != undefined) {
                return this.populatePicker(nextProps.countryId);
            }
        }
    
        populatePicker(countryId) {
            // This method fetches data from the API to store in the 'data' state object.
        }
    
        dropDownRenderRow(rowData, rowID, highlighted) {
            let evenRow = rowID % 2;
    
            return (
                <TouchableHighlight underlayColor='cornflowerblue'>
                    <View style={{backgroundColor: evenRow ? 'lemonchiffon' : 'white'}}>
                        <Text style={{color: 'black'}}>
                            {rowData.name}
                        </Text>
                    </View>
                </TouchableHighlight>
            );
        }
    
        dropDownRenderButtonText(rowData) {
            console.log('dropDownRenderButtonText', rowData);
            return rowData.name;
        }
    
        dropDownRenderSeparator(sectionID, rowID, adjacentRowHighlighted) {
            return (<View key={rowID} />);
        }
    
        dropDownOnSelect(rowID, rowData) {
            // Get the selected value and pass to parent component through onSelect() event in parent.
            this.props.onSelect(rowData.id);
        }
    
        render() {
            return (
                <View>
                    <Text>Home State</Text>
                    {this.state.data && this.state.data.length > 0 ?
                        <ModalDropdown defaultValue='Select one'
                              style={{flex:1}, {marginTop: 10}}
                              options={this.state.data}
                               onSelect={(rowID, rowData) => this.dropDownOnSelect(rowID, rowData)}
                              renderButtonText={(rowData) => this.dropDownRenderButtonText(rowData)}
                              renderRow={this.dropDownRenderRow.bind(this)}
                              renderSeparator={(sectionID, rowID, adjacentRowHighlighted) => this.dropDownRenderSeparator(sectionID, rowID, adjacentRowHighlighted)} />
                        :
                            <Text>No regions for country.</Text>
                    }
                </View>
            );
        }
    }
    

    我注意到'componentWillReceiveProps'功能正在阻止我的下拉列表中的选定值。但不幸的是,我需要这个函数,以便在传递来自父级的countryId值时更新道具。

    当我删除此dropDownOnSelect()函数中的this.props.onSelect(rowData.id);行时,会正确设置下拉值。我想是这种情况,因为我没有设定道具价值。

    我可以看到问题所在,但不是解决问题的方法。

    感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。发现一个简单的错误,检查nextProps.countryId是否与props.countryId不同,现在有意义了:

componentWillReceiveProps(nextProps) {
    if (nextProps.countryId && nextProps.countryId != this.props.countryId) {
        return this.populatePicker(nextProps.countryId);
    }
}