为什么 useState 提前调用我的函数
Why is useState calling my function early
我有一个与此等效的组件:
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' 按钮的等效项时,它 运行 的功能 (win/lose ) 早。
在 chrome 开发工具中,它正在调用 'setFunctionToRun' 并立即调用该函数(丢失)。
我期望的是,在单击说 'pick shell number 2' 按钮后,它应该将 functionToRun
设置为 () => win()
粗箭头功能。然后只有在点击 'Reveal Shell' 按钮时它才会调用任何东西。
解决方案是像这样制作 clickHandler:
const clickHandler = shellNumber%2?
() => pickShellFn(shellNumber, () => () => win())
: () => pickShellFn(shellNumber, () => () => lose(shellNumber));
现在调用函数时 returns 内部函数,准备好通过显示按钮调用。
这是因为useState
可以调用with a function
setPartOfState(prevState => doSomethingWith(previousState))
这意味着替代方法是调用:
setFunctionToRun(() => onConfirm);
它使用相同的签名,但不使用以前的状态或调用 onConfirm
。如果这个匿名函数不存在,它会在此时调用 onConfirm
而不是仅仅传递它。
我有一个与此等效的组件:
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' 按钮的等效项时,它 运行 的功能 (win/lose ) 早。
在 chrome 开发工具中,它正在调用 'setFunctionToRun' 并立即调用该函数(丢失)。
我期望的是,在单击说 'pick shell number 2' 按钮后,它应该将 functionToRun
设置为 () => win()
粗箭头功能。然后只有在点击 'Reveal Shell' 按钮时它才会调用任何东西。
解决方案是像这样制作 clickHandler:
const clickHandler = shellNumber%2?
() => pickShellFn(shellNumber, () => () => win())
: () => pickShellFn(shellNumber, () => () => lose(shellNumber));
现在调用函数时 returns 内部函数,准备好通过显示按钮调用。
这是因为useState
可以调用with a function
setPartOfState(prevState => doSomethingWith(previousState))
这意味着替代方法是调用:
setFunctionToRun(() => onConfirm);
它使用相同的签名,但不使用以前的状态或调用 onConfirm
。如果这个匿名函数不存在,它会在此时调用 onConfirm
而不是仅仅传递它。