代码之家  ›  专栏  ›  技术社区  ›  lentyai

React+Redux-初始加载时触发select onChange()

  •  3
  • lentyai  · 技术社区  · 7 年前

    我是一个新的反应和重复,所以请原谅我,如果答案是琐碎的,但经过广泛的搜索,我似乎没有找到这个简单问题的好答案。我有多个级联选择,其中数据根据之前的选择填充。当用户更改所选选项时,一切正常。然而,当数据最初加载到第一个select中时,我不知道如何触发onChange事件?以下是简化的组件:

    import React, {Component} from 'react';
    import PropTypes from 'prop-types';
    import { connect } from 'react-redux';
    import { locationActions } from '../../_actions';
    import { Input, Col, Label, FormGroup } from 'reactstrap';
    
    class HeaderSetup extends React.Component {
      constructor(props) {
        debugger;
        super(props);        
        this.state = { location: 'Select an Option'};
      }
    
      componentWillReceiveProps(nextProps) {
        if (nextProps.loading !== this.props.loading &&
            nextProps.success !== this.props.success &&
            !nextProps.loading && nextprops.success) {
          this.setState({ location: '' });
        }
      }
    
      onLocationChanged(e) {
        console.log(e.target.value);    
      }
    
      render() {
        const { locations } = this.props;
        return (
          <FormGroup row>
            <Label for="locations" sm={3}>Locations</Label>
            <Col sm={8}>
            {locations.items &&                    
              <Input type="select" name="locations" id="locations" 
                    onChange={this.onLocationChanged} 
                    value={this.state.location}>
                  {locations.items.map((location, index) =>
                      <option key={location.id}>
                          {location.locationName}                                
                      </option>
                  )}
              </Input>
              }          
            </Col>
          </FormGroup>       
        )
      }
    }
    
    function mapStateToProps(state) {
      debugger;
      const { locations } = state;
      return {
        locations
      };
    }
    
    export default connect(mapStateToProps)(HeaderSetup); 
    

    我只需要手动触发它吗?如果是的话,最好的地方/方式是什么?非常感谢您的帮助!

    1 回复  |  直到 7 年前
        1
  •  3
  •   thedude    7 年前

    因为您正在使用 controlled components 他们应该始终反映国家。在您的 onChange 回调您应该只更新状态,所有输入都应该相应地更新。

    如果您提供一个显示此问题的最小工作示例,我可能能够提供更多详细信息。

    下面是一个简单的设置示例:

    class App extends React.Component {
      state = {
        locations: []
      };
      componentDidMount() {
        setTimeout(() => { // simulate loading
          this.setState({
            loading: false,
            locations: [
              {
                id: 1,
                label: "Paris"
              },
              {
                id: 2,
                label: "Rome"
              }
            ]
          });
        }, 3000);
      }
      render() {
        return <MyForm locations={this.state.locations} initialLocation={2}/>;
      }
    }
    
    class MyForm extends React.Component {
      state = {
        initialLocation: null,
        location: ""
      };
    
      componentWillReceiveProps(nextProps) {
        this.setState({
          initialLocation: nextProps.initialLocation,
        })
      }
      
      onChange = e => {
        this.setState({
          location: e.target.value
        });
      };
    
      render() {
        const { locations } = this.props;
        return (
          <label>
            <div>Select a location:</div>
            {locations.length > 0 && (
              <select value={this.state.location || this.state.initialLocation} onChange={this.onChange}>
                {locations.map(({ id, label }) => (
                  <option key={id} value={id}>
                    {label}
                  </option>
                ))}
              </select>
            )}
          </label>
        );
      }
    }
    
    ReactDOM.render(<App />, document.body);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>