Bootstrap-multiselect:默认值和onChange不起作用

时间:2018-05-23 01:34:47

标签: javascript reactjs bootstrap-multiselect

我已经完成了大量的搜索工作,但却无法解决这个问题。看起来很简单。我顺便使用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. 当我更改所选选项

  3. 时,似乎没有发生任何事情

    修改

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

    1. 正如我所提到的,默认值没有填充;

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

      onStatusChanged =(e)=&gt; {     let search = this.state.searchForm;     search.status = e.target.selectedOptions;     this.setState({         searchForm:搜索     }) }

    3. <select id="example-multiple-selected" multiple="multiple" defaultValue={this.state.searchForm.status} onChange={this.onStatusChanged}>

      编辑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。

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

6 个答案:

答案 0 :(得分:0)

在反应中你无法直接修改状态, 您将不得不使用this.setState 这将为您的组件返回一个新状态,并在需要时做出反应。

对于您选择的问题,您必须使用“selected”属性呈现每个选项,以便选择它。

答案 1 :(得分:0)

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

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

如果你要传递一个函数,那么你需要绑定&#34;这个&#34;这样它就可以设置状态(如果你需要访问函数中的这个&#39;你只需要绑定(this)。

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

上工作的

答案 2 :(得分:0)

这个答案是使用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.log event.target可以看到所有值,如果您检查event.target[0].selected,则可以查看是否已选择第一个元素。同样,您必须遍历所有内容并查看所有内容已被选中。

答案 3 :(得分:0)

我可以看到你的代码遇到很多问题,首先,你的状态是错误的。尝试类似下面的内容。 ÿ

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

答案 4 :(得分:0)

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 :)

答案 5 :(得分:0)

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;