【问题标题】:How to change checkbox in react correctly? [closed]如何正确更改反应中的复选框? [关闭]
【发布时间】:2019-11-24 03:49:07
【问题描述】:

更改复选框值的正确方法是什么?

选项 1

import React, { useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [x, setX] = useState(false);

  const soldCheckbox = ({ target: { checked } }) => {
    console.log(x, checked);
    setX(checked);
  };
  return (
    <div>
      <input type="checkbox" checked={x} onChange={soldCheckbox} />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

选项 2

import React, { useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [x, setX] = useState(false);
  console.log(x);
  return (
    <div>
      <input type="checkbox" checked={x} onChange={() => setX(!x)} />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

其实我觉得没什么区别,只是想听听不一样的意见。也许是我不知道的事情,或者这个问题可能有其他解决方案。

【问题讨论】:

  • 两者都是正确的,但是如果您打算重用该方法,则从输入中抽象出该方法可能会有所帮助。
  • 在这种特定情况下,我会选择选项 2,我认为代码更简洁,setX 更改状态,如果我们知道值是,则不需要调用 setX 并从事件中提取值的函数x

标签: javascript reactjs checkbox


【解决方案1】:

两种方式都差不多,但是第一种其实比较多余,我们来分析一下原因:

第一种和第二种方法都在实现controlled组件

这意味着您提供了一个值和一种更改它的方法,因此更新和控制值的责任从组件中抽象出来。

但是为什么第一种方式是多余的呢?

您实际上不需要从e.target.checked 读取,因为它始终反映本地状态x,因此无需从e.target.checked 读取并通过执行以下操作来反转它:setX(!e.target.checked),因为@987654326 @ 和 e.target.checked 将始终相同。

注意事项

尽管在内联表达式(箭头函数)中执行onClick={e =&gt; parentHandler(e)} 很好,但您应该小心,像这样将它传递给输入不会导致任何问题,但是当您传递给实现的子组件时React.memoPureComponent 例如,这实际上每次都会重新渲染组件,导致总是创建函数的新实例(签名相同,但浅比较总是返回 false,因为它们是不同的实例),所以出于优化原因,最好的传递道具是这样的:&lt;Child onClick={this.clickHandler} id={item.id} /&gt; 和孩子:onClick={() =&gt; this.props.onClick(this.props.id)} 而不仅仅是:&lt;Child onClick={e =&gt; this.onClick(item.id)} /&gt;

【讨论】:

  • 想说选项 2 比选项 1 快吗? 2个选项也有多余的动作。你怎么能比较呢?
  • 没有更快。只是语义
  • 我理解正确吗?选项 1 更快,选项 2 干净。
  • 两个运行时几乎相同。唯一改变的是语义。两种方式都很好
【解决方案2】:

在这种特定情况下,我会选择选项 2,我认为代码更简洁。

setX 改变状态,如果我们知道值是 x,则不需要调用 setX 并从事件中提取值的函数。

【讨论】:

    【解决方案3】:

    我认为这完全取决于情况。

    如果您有很多表单和组件,第一个选项会更好。您可以使用一个处理程序处理所有问题。

    const handler = (e) => {
      const { target } = e;
      const value = target.type === 'checkbox' ? target.checked : target.value;
      const { name } = target;
    
      setForm( f => ({ ...f, [name]: value }));
    };
    

    其次,如果复选框为 1 并且应用程序必须以某种方式对其更改做出反应。 还有第三种方式uncontrolled inputs

    【讨论】:

      【解决方案4】:

      唯一的区别是干净的编码,如果你需要做一些除了改变状态之外的事情(例如调用 http 请求),第一种方法更好,如果你只需要复选框来工作并存储它的值,第二种方法很好。

      【讨论】:

        【解决方案5】:
        import React, { useState } from "react";
        import ReactDOM from "react-dom";
        
        import "./styles.css";
        
        function App() {
          const [x, setX] = useState(false);
        
          const soldCheckbox = ({ target: { checked } }) => {
            console.log(x, checked);
            setX(checked);
          };
          return (
            <div>
              <input type="checkbox" checked={x} onChange={soldCheckbox} />
            </div>
          );
        }
        
        const rootElement = document.getElementById("root");
        ReactDOM.render(<App />, rootElement);
        

        【讨论】:

        • 很高兴您花时间尝试回答这个问题,但您应该考虑添加一些解释,而不是仅仅粘贴一个 sn-p。
        【解决方案6】:

        我总是选择option 1,因为它是一种更通用的方式来定义表单字段更改事件。在大多数情况下,我有一些通用表单组件

        function SomeForm() {
           const [formData, setFormData] = useState({ name: "", accept: false });
           const onFieldChange = ({ target: { name, value, checked } }) => {
              if (typeof checked !== 'undefined') { // checking if we have a "checked" field inside target
                 setFormData({ [name]: checked });
              }
        
              setFormData({ [name]: value });
           }
        
           return (
              <form>
                <input type="text" name="name" value={formData.name} onChange={onFieldChange} />
                <input type="checkbox" name="accept" checked={formData.accept} onChange={onFieldChange} />
              </form>
           )
        }
        

        这背后的想法是,我们将以任何方式接收包含 checkedvalue 的目标 DOM 对象,因此我们可以将其设为通用。

        希望对你有帮助

        【讨论】:

          【解决方案7】:

          看起来你的两个选项是等效的。如果我们查看 React 提供的 onChange 事件(不是 html 提供的 change 事件)的文档,它会指出:

          onChange 事件的行为与您期望的一样:只要表单字段发生更改,就会触发此事件。

          我们故意不使用现有的浏览器行为,因为 onChange 对其行为的用词不当,而 React 依赖此事件来实时处理用户输入。

          DOM Elements

          因此,只需选择您认为可以生成更简洁代码的选项。

          【讨论】:

          • 好吧,在同一个目录中,以onChange={() =&gt; setX(!x)} 的方式创建函数并不总是正确的,可能会影响性能。
          • 你是说x的值有时会不正确?或者您是说将内联函数声明为道具是一种不好的做法?我以为 OP 是在问第一个问题。
          • 2.声明内联函数..它是这样写在文档中的。
          猜你喜欢
          • 2021-11-16
          • 2021-11-09
          • 2015-11-20
          • 2017-01-06
          • 2017-07-22
          • 2020-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多