我正在尝试创建一个自定义react钩子,以将9个元素的状态保存为true或false的对象。
let pads = {
Q: false,
W: false,
E: false,
A: false,
S: false,
D: false,
F: false,
Z: false,
X: false,
C: false,
};
export default () => {
const [padsPlaying, setPadsPlaying] = useState(pads);
return {
padsPlaying,
setPlayState: (element, state) => {
setPadsPlaying({ ...state, [element]: true });
},
};
};
在我的组件中,我导入了钩子,并像这样调用它:
const { padsPlaying, setPlayState } = usePlayState();
const playSound = (element) => {
// do some other stuff and in the end:
setPlayState(element.id, padsPlaying);
};
它起作用了,Q
的element.id用Q:true
和其他所有false
返回状态。但是,如果我再次运行该函数,它将Q
重置为其初始值false
,而新元素为true
。有人可以指出我正确的方向吗?我尝试了设置播放状态和初始化状态的不同组合,但是我感觉自己只是在拍摄蓝光,这里我想念的是什么?
编辑:我正在使用该状态以isPlaying的形式呈现true
或false
的组件列表
const makePads = preset[0].sounds.map((sound, i) => (
<DrumPad
key={sound.id}
id={sound.name}
name={sound.name}
source={sound.source}
trigger={sound.trigger}
isPlaying={padsPlaying[i]}
/>
));
已解决 我在使用旧状态的地方感到困惑,现在钩子看起来像这样,并且可以正常工作:)
export default () => {
const [padsPlaying, setPadsPlaying] = useState(initialPads);
const setPlayState = (id) => {
setPadsPlaying((state) => {
console.log(id);
return { ...state, [id]: true };
});
};
return [padsPlaying, setPlayState];
};
答案 0 :(得分:0)
我认为您访问状态不正确,但是我不确定,因为您并没有全部代码来查看如何访问状态。
我从您的代码中重新创建了一个小例子
let pads = {
Q: false,
W: false,
};
const usePlayState = () => {
const [padsPlaying, setPadsPlaying] = useState(pads);
const setPlayState = (element, state) => {
setPadsPlaying({ ...state, [element]: true });
}
return [
padsPlaying,
setPlayState,
];
};
function Testme() {
const [padsPlaying, setPlayState] = usePlayState();
useEffect(() => {
console.log(padsPlaying) // the proper way to access the new updated state is here
})
return (<div>
<button onClick={() => {
setPlayState('Q', padsPlaying);
// console.log(padsPlaying); // => Q still false because you still have the old stale state
}}>
Q
</button>
<button onClick={() => {
setPlayState('W', padsPlaying);
// console.log(padsPlaying); // => W still false because you still have the old stale state
}}>
W
</button>
</div>)
}
我指出了访问useEffect
中新状态的正确方法在哪里,它更等效于ComponentDidMount
,如果立即访问该状态,则会得到旧的{{1 }},您会发现state
仍为假,而从Q
内部读取值将给出新的真实值