admin管理员组

文章数量:1400033

Here my question is:

How can I change the state of my default set object using multiple select ?

Here let's say, I have states checkDevice and checkCountry, so in the below fiddle I did set all values to false.

I want to set the values of only those properties to true which are selected in the multi select dropdown.

For example: In multi select, if I just select US and UK then in my state is there a way to get something like:

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
      }
    }
  }

  ponentDidMount() {
    $(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'));
<link href=".98.0/css/materialize.min.css" rel="stylesheet" />
<script src="@16/umd/react.development.js"></script>
<script src="@16/umd/react-dom.development.js"></script>
<script src=".2.1/jquery.min.js"></script>
<script src=".100.2/js/materialize.min.js"></script>
<div id='root'></div>

Here my question is:

How can I change the state of my default set object using multiple select ?

Here let's say, I have states checkDevice and checkCountry, so in the below fiddle I did set all values to false.

I want to set the values of only those properties to true which are selected in the multi select dropdown.

For example: In multi select, if I just select US and UK then in my state is there a way to get something like:

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
      }
    }
  }

  ponentDidMount() {
    $(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'));
<link href="https://cdnjs.cloudflare./ajax/libs/materialize/0.98.0/css/materialize.min.css" rel="stylesheet" />
<script src="https://unpkg./react@16/umd/react.development.js"></script>
<script src="https://unpkg./react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<div id='root'></div>

CODEPEN, this will give you more freedom to play with.

UPDATE:

Here in the official documentation of React, we can see how to change the plete state, but is there a way to change just the property of the existing value

For Example::

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

But I don't think, I can get in this way. But I'm trying something like this.

Ans to questions that might help: Updating an object with setstate in react

Share Improve this question edited Dec 7, 2017 at 3:33 Dhaval Jardosh asked Dec 5, 2017 at 21:24 Dhaval JardoshDhaval Jardosh 7,3095 gold badges34 silver badges74 bronze badges 2
  • Not a good idea to mix jQuery and React but if you must, you have to have an event handler to actually handle the event – Andrew Li Commented Dec 5, 2017 at 21:31
  • i tried adding an event handler codepen.io/swyx/pen/MOMVMY but it seems the materialize jquery layer is intercepting the click, the event handler is not receiving any events at all. anyone have any ideas? – swyx Commented Dec 8, 2017 at 3:57
Add a ment  | 

2 Answers 2

Reset to default 5 +50
  1. materializecss won't trigger react onChange, so you have to bind in ponentDidMount

  2. value of select is controlled by react (virtual dom remember?), so you have to assign current value to select

where I changed your code

class Box extends React.Component {
  ponentDidMount() {

    //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}
    />)
  }
}

see codepen https://codepen.io/postor/pen/wPLyNq?editors=1011 for result

after you know how to do it yourself. I suggest you refer this https://github./react-materialize/react-materialize, this might save you some time

You must call a event handler from a onChange event to do that.

If you weren't using a fancy jQuery plugin, you could just:

handleChange(event) {
  this.setState({name: event.target.value})
}

render(){
  
  return <input onChange={event => this.handleChange(event)}
}

But as you are using this jQuery plugin which mutates the DOM without React knowledge, you should look into the plugin API and call this event handler within the jQuery Plugin event handler.

Lets assume material_select has a onChange option. You should call your ponent event handler within the material_select event handler.

handleChange(event) {
      this.setState({name: event.target.value})
    }

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

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

  }

If you manage to do that, changing the state is just a matter of array mapping, or diffing it with a library like lodash.

By the way, you shouldn't be using jQuery with React. You should look for a React wrapper/alternative to the jQuery plugin you intend to use. This library would expose its API by props, ensuring that you could program it in the React way.

本文标签: javascriptChange React State through Event HandlersStack Overflow