【问题标题】:using Material-ui checkboxes with the reactjs and redux使用带有 reactjs 和 redux 的 Material-ui 复选框
【发布时间】:2017-11-18 09:19:30
【问题描述】:

我想显示选中的复选框项目,为此我正在使用 material-ui checkbox

现在我只能显示带有复选框的项目,但无法显示所选项目。

我知道这很容易,但我是 reactjs 和 redux 的新手,所以很难开始。

希望得到帮助。

谢谢。

this.state = {
            data: [apple, kiwi, banana, lime, orange, grape],
        }}
    handleCheck(x) {
        this.state.checkedValues.push(x);
    }
render(){
       {this.state.data.map((x) =>
             <Checkbox
               label={x} key={x.toString()}
               onCheck={() => this.handleCheck(x)}
               checked=true
              }/>
          )}}

【问题讨论】:

  • 我已经回答了这个问题here。我希望它有所帮助。 :)
  • 请采纳答案,让访问这里的人快速了解解决方案

标签: reactjs checkbox material-ui react-state-management


【解决方案1】:

通过在onChange() 函数中添加事件作为参数来修改@BravoZulu 的答案。(另请注意,对于material-UI 复选框,请使用onChange() 而不是onCheck(),如官方documentation 所示)。另外,不要忘记在构造函数中绑定函数。我希望这对社区有所帮助。下面是代码。

    class App extends Component {
    constructor(props) {
        this.handleCheck = this.handleCheck.bind(this);
        super(props);
        this.state = {
        data: [apple, kiwi, banana, lime, orange, grape],
        checkedValues: []
        }
    }
    handleCheck(e,x) {
        this.setState(state => ({
        checkedValues: state.checkedValues.includes(x)
            ? state.checkedValues.filter(c => c !== x)
            : [...state.checkedValues, x]
        }));
    }

    render() {
        return (<div>
        { this.state.data.map(x =>
            <Checkbox
            label={x} key={x.toString()}
            onChange={e => this.handleCheck(e,x)}
            checked={this.state.checkedValues.includes(x)}
            />
        )}}
        </div>)
    }
}

【讨论】:

    【解决方案2】:

    handleCheck 函数中,您正在尝试错误地更新组件状态。您需要使用setState 来更改状态。在您的示例中,状态没有得到更新,因此这可能就是您没有看到任何被选中的原因。另外,将帮助清理您的示例:

    class CheckboxList extends React.Component{
      constructor() {
        super();
        this.state = {
            data: ['apple', 'kiwi', 'banana', 'lime', 'orange', 'grape'],
          checkedValues: []
        }
      }
      handleCheck(index) {
        this.setState({
            checkedValues: this.state.checkedValues.concat([index])
        });
        console.log(this.state.checkedValues.concat([index]))
      }
      render(){
       const checks = this.state.data.map( (item, index) => {
             return (
             <span key={item}>
                <input type="checkbox"
               value={item}
               onChange={this.handleCheck.bind(this, index)} //Use .bind to pass params to functions
               checked={this.state.checkedValues.some( selected_index => index === selected_index )}
              />
              <label>{item}</label>
             </span>)
       });
       return <div>{checks}</div>
      }
    }
    

    更新: 添加了工作jsfiddle

    【讨论】:

    • 他不能取消选中复选框,只能选中新的
    • 是的,我有点放弃尝试根据他们的例子来弄清楚他们想要做什么。希望这足以为他们指明正确的方向。
    • 哇,好吧,我想我实际上会尝试为您提供一些有用的东西。更新了我的答案。如果您有任何问题或想知道为什么/发生了什么,请告诉我。
    • checked={this.state.checkedValues.some( selected_index =&gt; index === selected_index )} 这一行发生了什么??
    • 更新了 jsfiddle 以处理取消选择:jsfiddle.net/jwm6k66c/2920
    【解决方案3】:

    聚会有点晚了,但这里有一个使用功能组件和钩子的解决方案

    import React, { useState } from 'react';
    import Checkbox from '@material-ui/core/Checkbox';
    
    const App = ({ data }) => {
      const [checked, setChecked] = useState([]);
    
      const handleCheck = (event) => {
        const { value } = event.target;
        setChecked(checked.includes(value) ? checked.filter(c => c !== value) : [...checked, value]);
      };
    
      return (
        <div>
          {data.map(({ value }) => (
             <Checkbox onChange={e => handleCheck(e)} checked {checked.includes(value)} />
          ))}
       </div>
      );
    };
    
    export default App;
    

    【讨论】:

    • 嗨,这个解决方案非常适合我。只有一个错误是您需要在 checked 之后放置一个等号 (=)。无论如何,谢谢。
    • 如何将选中的值传递给父组件?当我通过时,我在状态上落后了一步。
    【解决方案4】:

    在 React 中,您不应该将数据直接推送到您的状态。相反,请使用setState 函数。

    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          data: [apple, kiwi, banana, lime, orange, grape],
          checkedValues: []
        }
      }
      handleCheck(x) {
        this.setState(state => ({
          checkedValues: state.checkedValues.includes(x)
            ? state.checkedValues.filter(c => c !== x)
            : [...state.checkedValues, x]
        }));
      }
    
      render() {
        return (<div>
        { this.state.data.map(x =>
            <Checkbox
              label={x} key={x.toString()}
              onCheck={() => this.handleCheck(x)}
              checked={this.state.checkedValues.includes(x)}
             />
        )}}
        </div>)
      }
    }
    

    【讨论】:

    • 您不必每次都复制状态setState,一次只更新一个状态。
    • @ChaseDeAnda 是的,我编辑了所以我只返回状态的更新部分
    • @devanya 如果你对答案投了反对票,至少告诉我它有什么问题。
    • 但是您遇到了什么错误?我测试了这段代码,它可以工作
    • 箭头函数没有定义它们自己的上下文,所以'this'被设置为封闭的上下文,所以你不需要bindincludessome 相比在性能和偏好问题方面无关紧要,而不是最佳实践。
    【解决方案5】:

    当我终于找到解决这个问题的方法时,我也被这个问题困扰了很长一段时间。它永远不会适用于返回复选框的功能组件。我制作了一个单独的类组件并将其包装在 Redux Field 组件中,它运行良好。我真的不明白为什么它不适用于功能组件,因为它在他们的官方示例中显示。

    我已经编写了适合我的代码。希望对你有帮助:)

    class CheckBoxInput extends React.Component {
    
      onCheckBoxSelectChange = (input) => 
      {
        input.onChange();
        this.props.onSelectChange();
      }
    
      render() {
        const { label, input,} = this.props;
        let name = input.name;
    
        return (
          <div>
            <InputLabel htmlFor={label} style={{paddingTop: '15px'}}> {label} </InputLabel>
             <FormControl {...input} >
              <Checkbox
                name = {name}
                label = {label}
                color= "primary"
                checked={input.value ? true : false}
                onChange={() => this.onCheckBoxSelectChange(input)}
              />          
            </FormControl>
          </div>
    
        )
      }
    }
    
    const CheckBox = (props) => <Field component={CheckBoxInput} {...props} />;
    export default CheckBox;
    

    并使用此复选框组件:

     <CheckBox  name="isCurrent" label="Current" onSelectChange = {this.toggleCurrentEmployerSelection} />
    

    【讨论】:

      【解决方案6】:

      如果您使用的是对象而不是简单的数据类型,这里有一个可行的方法:

      class App extends Component {
        constructor(props) {
          super(props);
          this.state = {
            data: [{id: 1, name:'banana'},
                   {id: 2, name:'kiwi'}],
            checkedValues: []
          }
        }
        handleCheck(element) {
           const values = this.state.checkedValues.filter(e => e.id === element.id).length > 0
                  ? this.state.checkedValues.splice( this.state.checkedValues.findIndex( e => e.id === element.id),1)
                  : this.state.checkedValues.push(element);
           this.setState({
               checkedValues: values
           });
        }
      
        render() {
          return (<div>
          { this.state.data.map(el =>
              <Checkbox
                 checked={this.state.checkedValues.filter(e => e.id === el.id).length > 0}
                 onChange={this.handleCheck.bind(this, el)} //Use .bind to pass params to functions
                 value={el}
              />
          )}}
          </div>)
        }
      }
      

      所以基本上函数 handleCheck 所做的是检查所选对象是否在 checkedValues 数组中,如果是,则删除它(取消选中大小写),否则添加(大小写) check),我是否将选中的对象添加到 checkedValues 数组中。

      在Checkbox中checked检查checkedValues数组中是否有与当前循环对象相等的对象,(大小写checked/unchecked)

      【讨论】:

      • Uncaught TypeError: _this2.state.checkedValues.filter is not a function
      猜你喜欢
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      • 2021-01-28
      • 2019-03-17
      • 2021-07-04
      • 1970-01-01
      • 2016-12-04
      • 1970-01-01
      相关资源
      最近更新 更多