【问题标题】:Bootstrap-multiselect: default value and onChange not working引导多选:默认值和 onChange 不起作用
【发布时间】:2020-02-06 17:41:04
【问题描述】:

我已经进行了大量搜索,但无法使其正常工作。看起来很简单。顺便说一句,我正在使用 Bootstrap-multiselect。

class MyProject extends React.Component {
constructor(props) {
    super(props);
    this.state = { searchForm: { status: ["VALUE2","VALUE4"], otherprops: "blah" }, otherStates: "blah"};
    }

//blah blah
render() {
return (
<select id="example-multiple-selected" multiple="multiple" defaultValue={this.state.searchForm.status} onChange={(event) => this.state.searchForm.status = event.target.value}>
    <option value="VALUE1">VALUE1</option>
    <option value="VALUE2">VALUE2</option>
    <option value="VALUE3">VALUE3</option>
    <option value="VALUE4">VALUE4</option>
    <option value="VALUE5">VALUE5</option>
    <option value="VALUE6">VALUE6</option>
    <option value="VALUE7">VALUE7</option>
    <option value="VALUE8">VALUE8</option>
</select>
)
}}

问题

  1. 未选择默认值(VALUE2 和 VALUE4);

  2. 当我更改所选选项时似乎没有任何反应

编辑

似乎每个人都在谈论我没有正确设置状态的事实,我绝对同意。这是我犯的一个愚蠢的错误。 但是,我面临的根本问题仍然存在:

  1. 正如我所提到的,默认值不会被填充;

  2. onStatusChanged 函数根本没有被触发。我将调试点放在此函数中,但是当我更改所选选项时根本没有达到调试点。

    onStatusChanged = (e) => { 让搜索 = this.state.searchForm; search.status = e.target.selectedOptions; 这个.setState({ 搜索形式:搜索 }) }

&lt;select id="example-multiple-selected" multiple="multiple" defaultValue={this.state.searchForm.status} onChange={this.onStatusChanged}&gt;

编辑 2

最新代码:

class MyProject extends React.Component {
    constructor(props) {
        super(props);
        this.state = { searchForm: { status: ["VALUE2","VALUE4"], otherprops: "blah" }, otherStates: "blah"};
        this.onStatusChanged = this.onStatusChanged.bind(this);
        }

    //blah blah
    onStatusChanged = (e) => {
        let search = this.state.searchForm;
        search.status = e.target.selectedOptions;
        this.setState({
            searchForm: search
        })
    }

    render() {
    return (
    <select id="example-multiple-selected" multiple="multiple" value={this.state.searchForm.status} onChange={this.onStatusChanged}>
        <option value="VALUE1">VALUE1</option>
        <option value="VALUE2">VALUE2</option>
        <option value="VALUE3">VALUE3</option>
        <option value="VALUE4">VALUE4</option>
        <option value="VALUE5">VALUE5</option>
        <option value="VALUE6">VALUE6</option>
        <option value="VALUE7">VALUE7</option>
        <option value="VALUE8">VALUE8</option>
    </select>
    )
}}

重申我面临的问题:

  1. 正如我所提到的,默认值不会被填充;

  2. onStatusChanged 函数根本没有被触发。我将调试点放在此函数中,但是当我更改所选选项时根本没有达到调试点。似乎未检测到 onChange。

顺便说一句,如果有帮助,我正在使用 Bootstrap-multiselect 插件。

【问题讨论】:

    标签: javascript reactjs bootstrap-multiselect


    【解决方案1】:

    在 react 中你不能直接修改状态, 您将不得不使用 this.setState 这将为您的组件返回一个新状态,并且如果需要,react 将重新渲染。

    对于您选择的问题,您必须使用“selected”属性呈现每个选项才能被选中。

    【讨论】:

      【解决方案2】:

      这个答案使用的是 vanilla-js(没有 Bootstrap-multiselect),但应该可以正常工作。

      你不应该直接设置反应状态,反应状态是不可变的。你应该总是使用setState,所以this.state.searchForm.status = event.target.value应该是this.setState({searchForm: {status: event.target.value, otherprops:"blah"}})。您可以从React Docs 阅读有关setState 的信息

      event.target.value 不会为您提供所有选定的值。如果你console.logevent.target你可以看到所有的值,如果你检查event.target[0].selected你可以看到你的第一个元素是否被选中。同样,您必须遍历所有内容并查看已选择的所有内容。

      【讨论】:

        【解决方案3】:

        我可以看到您的代码存在很多问题,首先,您将状态设置错误。试试下面的东西。是的

        class MyProject extends React.Component {
            constructor(props) {
                super(props);
                this.state = {  searchForm: { status: ["VALUE2","VALUE4"], otherprops: "blah" }, otherStates: "blah"};
        
                    this.handlesChange = this.handlesChange.bind(this);
                }
        
                handlesChange(e){
                    let statuses  = this.state.searchForm.status;
                    let index = statuses.indexOf(e.target.value);
        
                    if(index > 0) {
                        this.setState({searchForm: statuses.splice(index, 1) })
                    } else {
                        statuses.push(e.target.value);
                        this.setState({ searchForm: statuses});
                    }
                }
        
            //blah blah
            render() {
                return (
                    <select id="example-multiple-selected" multiple="multiple" value={this.state.searchForm.status} onChange={this.handlesChange}>
                        <option value="VALUE1">VALUE1</option>
                        <option value="VALUE2">VALUE2</option>
                        <option value="VALUE3">VALUE3</option>
                        <option value="VALUE4">VALUE4</option>
                        <option value="VALUE5">VALUE5</option>
                        <option value="VALUE6">VALUE6</option>
                        <option value="VALUE7">VALUE7</option>
                        <option value="VALUE8">VALUE8</option>
                    </select>
            )
        
          }
        
        }
        

        注意:我没有测试过上面的代码。但是,无论您无法按照自己的方式设置集合,反应状态都是不可变的。请改用setState

        【讨论】:

        • @Henrix 你能不能像我上面那样使用value 而不是defaultValue。你的组件是受控的,应该保持这样。
        • 我试过了,但没有运气。但是,如果我像这样直接将值放入选择元素中,它会起作用:value={['VALUE2', VALUE4']}。但是为什么我不能使用状态变量呢?
        • setState 函数没有被调用对我来说是更严重的问题。
        • @Henrix 我们正在努力帮助您解决这个严重的问题。我让你试试是有原因的。您的方法可能不会在 uncontrolled react 组件中触发,因此需要进行更改。如果建议您应该尝试,因为其他人在您之前已经通过了,我们都在这里帮助您解决严重的问题。
        • 你能把上面问题中的代码换成最新的,让我们再看看吗?
        【解决方案4】:

        您不能只显式设置状态(期望在构造函数中)。在事件处理程序中(更改时),您必须使用 this.setState(...)。此外,您应该使用“selectedOptions”属性。

        onStatusChanged(event) {
          let searchForm = this.state.searchForm;
          searchForm.status = event.target.selectedOptions;
          this.setState({
            searchForm:searchForm
          });
        }
        
        ....
        
        <select id="example-multiple-selected" multiple="multiple" value={this.state.searchForm.status} onChange={this.onStatusChanged.bind(this)}>
        

        如果你要传入一个函数,那么你需要绑定“this”以便它可以设置状态(如果你需要在函数中访问'this',你只需要做bind(this)) .

        这是 JS Fiddle https://jsfiddle.net/69z2wepo/184044/

        【讨论】:

          【解决方案5】:
          I have modified your code to have multi select option. 
          
          #1 - I have added default selected values.
          #2 - handleMultiSelect method will loop through the items selected and we set it to state.
          #3 html content with values being printed based on our selected. 
          
           this.state = {
                          value: ["VALUE2", "VALUE3", "VALUE4"]
                      }
          
          
                  handleMultiSelect = (e) =>{
                      const options = e.target.options;
                      var value = [];
                      for (var i = 0, l = options.length; i < l; i++) {
                        if (options[i].selected) {
                          value.push(options[i].value);
                        }
                      }
          
                      this.setState({
                          value: value
                      })
          
                  }
          
          
             ########################HTML CODE ######################
              Selected Options {this.state.value} <br />
                              <select id="example-multiple-selected" 
                                      multiple 
                                      onChange={this.handleMultiSelect}
                                      value={this.state.value}>
                                  <option value="VALUE1">VALUE1</option>
                                  <option value="VALUE2">VALUE2</option>
                                  <option value="VALUE3">VALUE3</option>
                                  <option value="VALUE4">VALUE4</option>
                                  <option value="VALUE5">VALUE5</option>
                                  <option value="VALUE6">VALUE6</option>
                                  <option value="VALUE7">VALUE7</option>
                                  <option value="VALUE8">VALUE8</option>
                              </select>
          
          Hope this helps for you :)
          

          【讨论】:

            【解决方案6】:

            使用 Lodash 最简单的方法是:

            import React, { useState } from 'react';
            import map from 'lodash/map';
            
            const MultipleSelect = () => {
              const [selectedValues, setSelectedValues] = useState([]);
            
              const onMultipleSelectChange = event => {
                setSelectedValues(map(event.target.selectedOptions, option => option.value));
              };
            
              return (
                <select multiple value={selectedValues} onChange={onMultipleSelectChange}>
                  <option value="value-1">value 1</option>
                  <option value="value-2">value 2</option>
                  <option value="value-3">value 3</option>
                </select>
              );
            };
            
            export default MultipleSelect;
            

            【讨论】:

              猜你喜欢
              • 2019-05-17
              • 2017-11-22
              • 2013-08-21
              • 1970-01-01
              • 2013-11-03
              • 1970-01-01
              • 2019-02-21
              • 1970-01-01
              相关资源
              最近更新 更多