一个简短的React教程,通过实例为初学者介绍如何创建一个不确定的React Checkbox,它使用不确定的状态(也叫三态)。
让我们从之前教程中的一个复选框例子开始:
const App = () => {
const [checked, setChecked] = React.useState(false);
const handleChange = () => {
setChecked(!checked);
};
return (
<div>
<Checkbox
label="Value"
value={checked}
onChange={handleChange}
/>
<p>Is checked? {checked.toString()}</p>
</div>
);
};
const Checkbox = ({ label, value, onChange }) => {
return (
<label>
<input type="checkbox" checked={value} onChange={onChange} />
{label}
</label>
);
};
现在我们想扩展这个复选框的功能,以处理三态而不是双态。首先,我们需要将我们的状态从布尔值转换为枚举值,因为只有这样我们才能创建一个三态。
const CHECKBOX_STATES = {
Checked: 'Checked',
Indeterminate: 'Indeterminate',
Empty: 'Empty',
};
const App = () => {
const [checked, setChecked] = React.useState(CHECKBOX_STATES.Empty);
const handleChange = () => {
let updatedChecked;
if (checked === CHECKBOX_STATES.Checked) {
updatedChecked = CHECKBOX_STATES.Empty;
} else if (checked === CHECKBOX_STATES.Empty) {
updatedChecked = CHECKBOX_STATES.Checked;
}
setChecked(updatedChecked);
};
return (
<div>
<Checkbox
label="Value"
value={checked}
onChange={handleChange}
/>
<p>Is checked? {checked}</p>
</div>
);
};
const Checkbox = ({ label, value, onChange }) => {
return (
<label>
<input
type="checkbox"
checked={value === CHECKBOX_STATES.Checked}
onChange={onChange}
/>
{label}
</label>
);
};
我们有和以前一样的行为,但是使我们的复选框能够有两个以上的状态。
接下来是复选框的不确定状态。不幸的是,它不能通过HTML来分配,我们需要在这里使用一个强制性的DOM操作。幸运的是,React有Refs的概念,使React开发者能够访问DOM元素:
const Checkbox = ({ label, value, onChange }) => {
const checkboxRef = React.useRef();
return (
<label>
<input
ref={checkboxRef}
type="checkbox"
checked={value === CHECKBOX_STATES.Checked}
onChange={onChange}
/>
{label}
</label>
);
};
通过对复选框元素的访问,我们可以强制性地设置和取消复选状态,而不是以声明的方式使用HTML:
const Checkbox = ({ label, value, onChange }) => {
const checkboxRef = React.useRef();
React.useEffect(() => {
if (value === CHECKBOX_STATES.Checked) {
checkboxRef.current.checked = true;
} else {
checkboxRef.current.checked = false;
}
}, [value]);
return (
<label>
<input ref={checkboxRef} type="checkbox" onChange={onChange} />
{label}
</label>
);
};
React的useEffect Hook在每次依赖数组(这里是:value )中的变量发生变化时都会执行其传递的副作用函数。然后在侧效果函数中,我们评估该值:如果是选中的,我们以编程方式将复选框的内部HTML状态设置为选中;反之则为未选中的状态。
最后,我们也可以用这种方式来分配不确定的状态:
const Checkbox = ({ label, value, onChange }) => {
const checkboxRef = React.useRef();
React.useEffect(() => {
if (value === CHECKBOX_STATES.Checked) {
checkboxRef.current.checked = true;
checkboxRef.current.indeterminate = false;
} else if (value === CHECKBOX_STATES.Empty) {
checkboxRef.current.checked = false;
checkboxRef.current.indeterminate = false;
} else if (value === CHECKBOX_STATES.Indeterminate) {
checkboxRef.current.checked = false;
checkboxRef.current.indeterminate = true;
}
}, [value]);
return (
<label>
<input ref={checkboxRef} type="checkbox" onChange={onChange} />
{label}
</label>
);
};
别忘了,首先要在状态变化时分配适当的值:
const App = () => {
const [checked, setChecked] = React.useState(CHECKBOX_STATES.Empty);
const handleChange = () => {
let updatedChecked;
if (checked === CHECKBOX_STATES.Checked) {
updatedChecked = CHECKBOX_STATES.Empty;
} else if (checked === CHECKBOX_STATES.Empty) {
updatedChecked = CHECKBOX_STATES.Indeterminate;
} else if (checked === CHECKBOX_STATES.Indeterminate) {
updatedChecked = CHECKBOX_STATES.Checked;
}
setChecked(updatedChecked);
};
return (
<div>
<Checkbox
label="Value"
value={checked}
onChange={handleChange}
/>
<p>Is checked? {checked}</p>
</div>
);
};
就这样了。通过引入不确定状态,我们将我们的React复选框组件从双状态转变为三状态。我希望这个教程对你有用,如果你正好需要一个有三种状态的复选框。