我有一个与此等效的组件:
const PickAShell = () => {
const [functionToRun, setFunctionToRun] = useState(() => {});
const [shellPicked, setShellPicked] = useState(0);
const shells = [1,2,3,4,5];
const pickShellFn = (shellNumber, onConfirm) => {
setFunctionToRun(onConfirm);
setShellPicked(shellNumber);
}
const win = () => setShellPicked(0)
&& alert('You Win');
const lose = (shellNumber) => setShellPicked(0)
&& alert('nothing under shell '+shellNumber)
return (
<div>
{shells.map(shellNumber => {
const clickHandler = shellNumber%2?
() => pickShellFn(shellNumber, () => win())
: () => pickShellFn(shellNumber, () => lose(shellNumber));
return <Button onClick={clickHandler}>{`pick shell number ${shellNumber}`}</Button>
}) }
{shellPicked? (<Button onClick={functionToRun}>Reveal Shell</Button>): null}
</div>
)
}
我所看到的是,当我运行它时,我单击了等效的“ pick shell number X”(选择壳号X)按钮,它会尽早运行功能(赢/输)。
在chrome开发工具中,它正在调用“ setFunctionToRun”并立即调用该函数(丢失)。
我期望的是,单击说“ pick shell number 2”按钮后,应该将functionToRun
设置为() => win()
粗箭头功能。然后只有在单击“显示外壳”按钮时,它才能调用任何东西。
答案 0 :(得分:-1)
解决方案是使clickHandler像这样:
const clickHandler = shellNumber%2?
() => pickShellFn(shellNumber, () => () => win())
: () => pickShellFn(shellNumber, () => () => lose(shellNumber));
现在,当调用函数时,它会返回内部函数,可以通过显示按钮调用。
这是因为useState
可以称为with a function
setPartOfState(prevState => doSomethingWith(previousState))
这意味着替代方法是致电:
setFunctionToRun(() => onConfirm);
使用相同的签名,但不使用先前的状态或调用onConfirm
。如果不存在该匿名函数,那么它将在此时调用onConfirm
而不是直接传入它。