通过事件处理程序更改React状态

时间:2017-12-05 21:24:59

标签: javascript jquery reactjs

我的问题是:

如何使用多个选择来更改默认设置对象的状态?

我们在这里说,我有checkDevicecheckCountry,所以在下面的小提琴中,我确实将所有值设置为false

我想将这些属性的值设置为true,这些属性是在多选下拉列表中选择的。

例如:在多选中,如果我只选择USUK,那么在我的状态下有一种方法可以获得如下内容:

checkCountry: 
     {
        'US': true,
        'UK': true,
        'JP': false
      }



class Box extends React.Component {

  constructor() {
    super();
    this.state = {
      checkDevice: {
        'iPhone 4': false,
        'iPhone 5': false,
        'iPhone 6': false,
        'iPhone 7': false,
        'iPhone 8': false,
        'iPhone X': false,
      },
      checkCountry: {
        'US': false,
        'UK': false,
        'JP': false
      }
    }
  }

  componentDidMount() {
    $(document).ready(function() {
      $('#country').material_select();
    });
    $(document).ready(function() {
      $('#device').material_select();
    });
  }

  render() {
    return ( 
    <div className="card" style={{width:900,margin: 'auto'}}>
        <form className="row">
          <div className='col s6'>
            <div className="input-field">
              <select value="" multiple id="country">
                <option value="" disabled selected>Choose your option</option>
                <option value="1">US</option>
                <option value="2">UK</option>
                <option value="3">JP</option>
              </select>
              <label>Country</label>
            </div>
          </div>
          <div className='col s6'>
            <div className="input-field">
              <select value="" multiple id="device">
                <option value="" disabled selected>Choose your option</option>
                <option value="1">iPhone 4</option>
                <option value="2">iPhone 5</option>
                <option value="3">iPhone 6</option>
                <option value="4">iPhone 7</option>
                <option value="5">iPhone 8</option>
                <option value="6">iPhone X</option>
              </select>
              <label>Devices</label>
            </div>
          </div>
        </form>
        <div className="row">
        <div className="col s6">
          <pre>{JSON.stringify(this.state.checkCountry,null,2)}</pre>
        </div>
        <div className="col s6">
          <pre>{JSON.stringify(this.state.checkDevice,null,2)}</pre>
        </div>
        </div>
       </div>
    );
  };
}

ReactDOM.render( < Box / > , document.getElementById('root'));
&#13;
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css" rel="stylesheet" />
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<div id='root'></div>
&#13;
&#13;
&#13;

CODEPEN ,这将为您提供更多自由游戏。

更新

在React的官方文档中,

Here ,我们可以看到如何更改完整状态,但是有没有办法只更改现有值的属性

例如:

handleChange(event){
    this.setState({checkCountry["event.target.value"] === true ? false: true});
} 

但我不认为,我可以这样做。但我尝试这样的事情。

回答可能有用的问题: Updating an object with setstate in react

2 个答案:

答案 0 :(得分:5)

  1. materializecss不会触发反应onChange,因此您必须绑定componentDidMount

  2. select的{li>

    value由react(virtual dom记得?)控制,所以你必须指定当前值才能选择

    我改变了你的代码

    class Box extends React.Component {
      componentDidMount() {
    
        //binding onchange
        $(this.countrySelect)
          .on("change", () => {
            let checkCountry = {
              US: false,
              UK: false,
              JP: false
            };
            let val = $(this.countrySelect).val();
            console.log(val);
            val.forEach(x => {
              checkCountry[x] = true;
            });
            this.setState({
              checkCountry
            });
          })
          .material_select();
      }
    
      render() {
        const { checkCountry } = this.state;
        const countryVal = Object.keys(checkCountry).filter(x => checkCountry[x]);
         //assigin value
        return (<select 
          ref={countrySelect => (this.countrySelect = countrySelect)}
          value={countryVal}
        />)
      }
    }

    请参阅codepen https://codepen.io/postor/pen/wPLyNq?editors=1011了解结果

    知道如何自己做之后。我建议你参考这个https://github.com/react-materialize/react-materialize,这可能会节省你一些时间

答案 1 :(得分:2)

您必须从onChange事件调用事件处理程序才能执行此操作。

如果你没有使用花哨的jQuery插件,你可以:

&#13;
&#13;
handleChange(event) {
  this.setState({name: event.target.value})
}

render(){
  
  return <input onChange={event => this.handleChange(event)}
}
&#13;
&#13;
&#13;

但是当你使用这个jQuery插件来改变没有React知识的DOM时,你应该查看插件API并在jQuery Plugin事件处理程序中调用这个事件处理程序。

让我们假设material_select有一个onChange选项。您应该在material_select事件处理程序中调用组件事件处理程序。

&#13;
&#13;
handleChange(event) {
      this.setState({name: event.target.value})
    }

    render(){
      
      return "Your current markup here"
    }

  componentDidMount() {
    $(document).ready(function() {
      $('#country').material_select({
        onChange: (event) => this.onChange(event)
      });
    });

  }
&#13;
&#13;
&#13;

如果你设法做到这一点,改变状态只是数组映射的问题,或者用像lodash这样的库来区分它。

顺便说一句,你不应该在React中使用jQuery。你应该寻找你想要使用的jQuery插件的React包装器/替代品。该库将通过props公开其API,确保您可以以React方式对其进行编程。