反应复选框不更新

Posted

技术标签:

【中文标题】反应复选框不更新【英文标题】:React Checkbox Does Not Update 【发布时间】:2017-09-14 13:28:46 【问题描述】:

我想在每次将复选框切换为 true 时更新数组。使用此当前代码,如果我单击一个复选框,它将记录它是错误的。即使我刚刚更新了状态。 setState 是否只需要一些时间,例如 API 调用?这对我来说没有意义。

import React, Component from 'react';

class Person extends Component 

  constructor(props) 
    super(props);

    this.state = 
      boxIsChecked: false
    ;

    this.checkboxToggle = this.checkboxToggle.bind(this);
  

  checkboxToggle() 
    // state is updated first
    this.setState( boxIsChecked: !this.state.boxIsChecked );
    console.log("boxIsChecked: " + this.state.boxIsChecked);
    if (this.state.boxIsChecked === false) 
      console.log("box is false. should do nothing.");
    
    else if (this.state.boxIsChecked === true) 
      console.log("box is true. should be added.");
      this.props.setForDelete(this.props.person._id);
    

  

    render() 
        return (
          <div>
            <input type="checkbox" name="person" checked=this.state.boxIsChecked onClick=this.checkboxToggle />
            this.props.person.name (this.props.person.age)
          </div>
        );
    


export default Person;

我尝试过 onChange 而不是 onClick。我觉得我已经在遵循我从here 和here 阅读的关于基本组件公式的建议。我将 Redux 用于其他值会影响任何事情吗?有没有办法只读取复选框是什么,而不是试图控制它? (复选框本身工作正常,并且 DOM 会更新它是否被选中。)

【问题讨论】:

您的代码 sn-p 根本没有使用 Redux。它正在使用常规的 React 状态。 是的,我只是在检查是否存在可能导致某些问题的副作用。我也在组件中使用了一些 Redux 操作。 【参考方案1】:

在调用 setState() 之后,您无法访问 state 的更新值。

如果你想做一些更新状态值的事情,你可以这样做。即在setState()回调函数内

     checkboxToggle() 
        // state is updated first
        this.setState( boxIsChecked: !this.state.boxIsChecked ,()=>

        console.log("boxIsChecked: " + this.state.boxIsChecked);
        if (this.state.boxIsChecked === false) 
          console.log("box is false. should do nothing.");
        
        else if (this.state.boxIsChecked === true) 
          console.log("box is true. should be added.");
          this.props.setForDelete(this.props.person._id);
        


);

【讨论】:

嗯,这是有道理的。我不知道为什么我没有想到 setState 可能会进行回调。我们可以使用 Promise 你知道吗? 为什么要使用promise,使用promise想要达到什么目的? SetState 回调将做你需要的。对吗? 我只是好奇。我更倾向于使用承诺。 ;P React 的 setState() 不返回承诺。坚持回调的。 @GabrielKunkel 你可以wrap it in a promise,【参考方案2】:

setState() 确实没有马上反映:

Read here in the docs:

setState() 将组件状态的更改排入队列并告诉 React 这个组件及其子组件需要重新渲染 更新状态。这是您用来更新用户的主要方法 响应事件处理程序和服务器响应的接口。

将 setState() 视为请求而不是立即命令 更新组件。为了获得更好的感知性能,React 可能 延迟它,然后一次更新几个组件。反应 不保证立即应用状态更改。

setState() 并不总是立即更新组件。有可能 批处理或推迟更新。这使得阅读 this.state 就在调用 setState() 之后,这是一个潜在的陷阱。相反,使用 componentDidUpdate 或 setState 回调(setState(updater, 回调)),其中任何一个都保证在更新后触发 已应用。如果需要根据前面的设置状态 状态,请阅读下面的更新程序参数。

setState() 总是会导致重新渲染,除非 shouldComponentUpdate() 返回 false。如果可变对象正在 使用和条件渲染逻辑无法实现 shouldComponentUpdate(),只有在新状态时才调用 setState() 与之前的状态不同将避免不必要的重新渲染。

and here some experiments

所以最好抓住事件并检查它,而不是依赖于this.setState() 类似的东西:

handleChange: function (event)  
   //you code
    if (event.target.checked) 
      console.log("box is true. should be added.");
      this.props.setForDelete(this.props.person._id);
    

  

    render() 
            return (
              <div>
                <input type="checkbox" name="person" checked=this.state.boxIsChecked 
                   onChange=this.handleChange.bind(this)/>
                this.props.person.name (this.props.person.age)
              </div>
            );
        

【讨论】:

非常感谢。这可能是一个基本问题,但是您是否可以将任何资源链接到有关捕获或使用事件的讨论,例如检查或取消检查?我宁愿只观察复选框是否被选中,而不必跟踪状态值。 @GabrielKunkel 我编辑了代码 sn-p。我就是这样做的。请尝试。但是你仍然需要使用setState来反映复选框中的变化,或者完全移除checked属性。 @GabrielKunkel 这个链接可能会有所帮助,你也可以有一堆关键词可以在进一步的研究中使用:help.dottoro.com/ljihlcqe.php 很好的答案,很好的解释。谢谢...!【参考方案3】:

我知道该线程已得到答复,但我也有解决方案,您看到复选框未使用提供的 setState 值进行更新,我不知道此问题的确切原因,但这里有一个解决方案.

<input
  key=Math.random()
  type="checkbox"
  name="insurance"
  defaultChecked=data.insurance
 />

通过给出 random 的键值,复选框被重新渲染并更新复选框的值,这对我有用。我也在使用钩子,但它应该适用于基于类的实现。

参考:https://www.reddit.com/r/reactjs/comments/8unyps/am_i_doing_stupid_or_is_this_a_bug_checkbox_not/

【讨论】:

这显然是最好的解决方案。 +1 这个答案对我帮助很大。【参考方案4】:

我来到这里试图弄清楚为什么我的复选框(使用 HTM 标记的模板库呈现)不起作用。

return html`
  ...
  <input type="checkbox" checked=$state.active ? "checked" : null />
  ...
`;

事实证明,我对那个三元运算符太努力了。这工作正常:

return html`
  ...
  <input type="checkbox" checked=$state.active />
  ...
`;

【讨论】:

【参考方案5】:

反应解决方案:

HTML:

<input type="checkbox" ref=checkboxRef onChange=handleChange/>

JS:

const checkboxRef = useRef("");
  const [checkbox, setCheckbox] = useState(false);
  const handleChange = () => 
    setCheckbox(checkboxRef.current.checked);
  ;

现在你的真/假值存储在复选框变量中

【讨论】:

【参考方案6】:

扩大没有新手的答案;什么对我有用:

从 onChange Event-Listener 中删除 preventDefault() 但这对我来说并不合适,因为我只想对更新值做出反应。而且它可能并不适用于所有情况,例如 OP。 在键中包含检查值,如key="agree_legal_checkbox" + legalcheckboxValue checked=legalcheckboxValue

我从新手的回答中得到了这两种解决方案,但是使用 math.random 键感觉不对。使用checked的值会导致key只有在checked的值改变时才会改变。

(没有足够的声誉来简单地将其发布为评论,但仍想分享)

【讨论】:

以上是关于反应复选框不更新的主要内容,如果未能解决你的问题,请参考以下文章

反应复选框不切换

反应,为啥标签不为复选框触发 onChange?

反应复选框不发送 onChange

如何在反应表中使用另一个不确定的复选框列

反应故事书复选框更改处理程序不起作用

复选框 Shiny R 的反应性 k 均值分析