更改复选框值的正确方法是什么?
选项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);
实际上,我认为没有区别,但是我只是想听听不同的意见。也许我不知道一些,或者对此问题可能还有其他解决方案。
答案 0 :(得分:16)
我认为这完全取决于情况。
如果您有很多表单和组件,则第一种选择会更好。您可以使用一个处理程序来处理所有操作。
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的第三种方式。
答案 1 :(得分:9)
两种方法几乎相同,但是第一种选择实际上是多余的,让我们分析原因:
controlled
组件这意味着您正在提供一个值和一种更改它的方法,因此从组件中提取了更新和控制值的职责。
您实际上不需要读取e.target.checked
,因为它总是反映本地状态x
,因此无需读取e.target.checked
并通过以下操作将其反转: setX(!e.target.checked)
因为x
和e.target.checked
将始终相同。
注意事项
即使在内联表达式(箭头函数)中执行
onClick={e => parentHandler(e)}
也很好,您应该小心,像这样将其传递给输入不会造成任何问题,但是当您传递给子组件时例如,它实现了React.memo
或PureComponent
,实际上每次都会重新渲染该组件,因为总是创建该函数的新实例(签名是相同的,但是浅表比较总是返回false原因)它们是不同的实例),因此出于优化原因,总是最好通过以下道具:<Child onClick={this.clickHandler} id={item.id} />
,在子对象上:onClick={() => this.props.onClick(this.props.id)}
,而不只是:<Child onClick={e => this.onClick(item.id)} />
答案 2 :(得分:7)
在这种情况下,我会选择选项2(我认为更干净的代码)。
setX更改状态,如果我们知道值是x,则不需要调用setX并从事件中提取值的函数。
答案 3 :(得分:1)
唯一的区别是干净的编码,如果您需要做一些其他事情来改变状态(例如,调用http请求),则第一种方法更好;而如果只需要复选框来工作并存储其值,第二种方法就更好。 / p>
答案 4 :(得分:1)
您的两个选项似乎都相等。如果我们看一下React提供的onChange事件的文档(不是html提供的change事件),它会指出:
onChange事件的行为与您预期的一样:每当更改表单字段时,都会触发此事件。
我们有意不使用现有的浏览器行为,因为onChange对其行为不恰当,并且React依赖于此事件来实时处理用户输入。
因此,只需选择您认为可以生成更简洁代码的选项即可。
答案 5 :(得分: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);
答案 6 :(得分:0)
我总是选择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>
)
}
其背后的想法是,我们将以任何方式接收包含checked
和value
的目标DOM对象,因此我们可以使其通用。
希望这会有所帮助