使用带有 reactjs 和 redux 的 Material-ui 复选框

Posted

技术标签:

【中文标题】使用带有 reactjs 和 redux 的 Material-ui 复选框【英文标题】:using Material-ui checkboxes with the reactjs and redux 【发布时间】: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。我希望它有所帮助。 :) 请采纳答案,让访问这里的人快速了解解决方案 【参考方案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

以上是关于使用带有 reactjs 和 redux 的 Material-ui 复选框的主要内容,如果未能解决你的问题,请参考以下文章

在带有Redux的ReactJS中避免竞争条件

如何使用 reactjs 和 redux 处理导航

Redux - ReactJS 应用程序不会重新渲染(尽管 JSON.parse 用于新对象)

Redux/Flux(使用 ReactJS)和动画

使用 ReactJS + Redux 时需要 componentWillReceiveProps 和 replaceProps 吗?

采用reactjs 开发时,redux 和 react-route 是怎么配合使用的