Wok*_*ers 1 javascript reactjs react-hooks
我有几个状态,我只想为所有状态编写 1 个处理程序。更改时,只有 1 个处理程序会触发并仅在状态发生更改时更改状态。
我有这样的基于类的组件的解决方案
handleChange (evt) {
this.setState({ [evt.target.name]: evt.target.value });
}
Run Code Online (Sandbox Code Playgroud)
但是当我使用基于函数的组件时,我不知道如何使用。
export default function DateBar(props)
{
let date = new Date();
let i = 1;
const days = Array.from({length: new Date(date.getYear(), date.getMonth() + 1, 0).getDate()}).map(() => <option key = {uuidv4()} value={i}>{i++}</option>);
const monthOpts = props.months.map(month => <option key = {uuidv4()} value={month} name = {month} id = {month}>{month}</option>);
const yearsOpts = props.years.map(year => <option key = {uuidv4()} value ={year} name = {year} id = {year}>{year}</option>);
// states
const [today, setToday] = useState("");
const [thisMonth, setThisMonth] = useState("");
const [year, setYear] = useState("");
useEffect(() =>
{
setToday(date.getDate());
setThisMonth(props.months[date.getMonth()]);
setYear(date.getYear());
}, []);
const handleChange = () =>
{
// for example, if day is changed, i want to call setToday() somehow..
}
return(
<div className="DateBarRoot">
<FormControl className="formControl input" variant="outlined">
<InputLabel htmlFor="today">Day</InputLabel>
<Select
native
value={today}
onChange={handleChange}
label = 'day'
inputProps={{
name: 'today',
id: 'today',
}}
>
{days}
</Select>
</FormControl>
<FormControl className="formControl input" variant="outlined">
<InputLabel htmlFor="month">Month</InputLabel>
<Select
native
value={thisMonth}
onChange={handleChange}
label = 'month'
inputProps={{
name: 'thisMonth',
id: 'thisMonth',
}}
>
{monthOpts}
</Select>
</FormControl>
<FormControl variant="outlined" className="formControl input">
<InputLabel htmlFor="year">Year</InputLabel>
<Select
native
className="select"
value={year}
onChange={handleChange}
label = 'year'
inputProps={{
name: 'year',
id: 'year',
}}
>
{yearsOpts}
</Select>
</FormControl>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
预先非常感谢。
您可以有一个保存这些值的状态项。事实上,useState文档已经涵盖了这一点:
笔记
setState与类组件中的方法不同,useState它不会自动合并更新对象。您可以通过将函数更新器形式与对象扩展语法相结合来复制此行为:Run Code Online (Sandbox Code Playgroud)const [state, setState] = useState({}); setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; });另一个选项是
useReducer,它更适合管理包含多个子值的状态对象。
在你的情况下,它可能是:
const [values, setValues] = useState({}); // Or maybe a Map
// ...
const handleChange = (event) => {
setValues(values => {
return {...values, [event.target.name]: event.target.value};
});
};
Run Code Online (Sandbox Code Playgroud)
或者进行一些解构:
const [values, setValues] = useState({}); // Or maybe a Map
// ...
const handleChange = ({target: {name, value}}) => {
setValues(values => {
return {...values, [name]: value};
});
};
Run Code Online (Sandbox Code Playgroud)
或者,正如上面所说,您可以在事件目标名称上使用useReducerand ,可能是 a 。switch