如何在新对象Time
上添加新key: 1
的持续更新状态?
这是它的外观:
time: ["21:10:56", "21:10:56", "21:10:56"]
当前,每次我按一个键都会创建一个新对象。
当我在Number Two
输入中输入值以拥有自己的key: 2
对象并向其添加时间值时,情况也是如此。
const {useState, useEffect} = React;
const App = () => {
const [state, setState] = useState([])
const handleChange = (e, key) => {
const d = new Date()
const time = `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`
setState((prevState) => {
// console.log(state[0].time)
// const initialArray = state.concat({ time })
// console.log('test', initialArray)
// const newArray = [...initialArray, { time }]
return [...prevState, { key, time: [time] }]
// return prevState.concat({ key, time: [time] })
})
}
useEffect(() => {
console.log(state)
}, [state])
return (
<div>
<div>
<p>
{`Number One:`}
<input type="number" onChange={(e) => handleChange(e, 1)} />
</p>
</div>
<div>
<p>
{`Number Two:`}
<input type="number" onChange={(e) => handleChange(e, 2)} />
</p>
</div>
</div>
);
};
ReactDOM.render(
<App/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
答案 0 :(得分:2)
您正在通过执行return [...prevState, { key, time: [time] }]
向prevState添加新项目。取而代之的是,您需要找到与被调用的句柄更改具有相同键的项,并将时间推送到时间数组,或者如果找不到该项,则创建一个新对象。
const handleChange = (e, key) => {
const d = new Date()
const time = `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`
setState((prevState) => {
let object = prevState.find(obj => obj.key === key);
if (!object) {
prevState.push({key, time: [time]});
}
else object.time.push(time)
return prevState;
})
}
答案 1 :(得分:2)
我将使用key
作为属性名称和time
作为值将状态更改为对象,然后使用类似JakeParis' answer的对象。
但是,如果那是您所坚持的:
setState((prevState) => {
return [...(prevState?.filter(el => el.key !== key) || []), {
key,
time: [...(prevState?.find(el => el.key === key)?.time || []), time]
}];
})
这将返回一个新数组,该数组具有(第一次扩展)键处于不同状态的先前状态中的所有元素,然后返回具有您正在使用的键的对象的新副本,且时间值设置为具有该键的元素的时间数组的先前值的数组(如果为新键,则为空数组),以及传递的时间。
以上内容适用于browsers supporting optional chaining,其中的数目令人惊讶。这是适用于旧版浏览器的一种:
setState((prevState) => {
return prevState ? [...prevState.filter(el => el.key !== key), {
key,
time: [...(prevState.find(el => el.key === key) ? prevState.find(el => el.key === key).time : []), time]
}] : [{key, time: [time] }];
})
答案 2 :(得分:1)
我相信您的错误在这里:
return [...prevState, { key, time: [time] }]
应该是:
const newTimeArray = [...prevState[key].time];
newTimeArray.push(time);
return { ...prevState, key: newTimeArray };
HereticMonkey指出state是一个数组而不是对象,因此应该返回一个数组。但是总体思路仍然成立。