我有一个Parent-Child组件结构。在parent中,我有一个调用Web服务的函数,需要几秒钟才能完成。从parent中,我将此函数作为prop传递给child。Child组件显示按钮,并将onClick
绑定到parent的函数。我如何在单击后禁用child中的按钮,直到parent的回调函数完成执行,然后重新启用它们?
例如,在下面的代码中,doOperation
是这样一个函数,具有setTimeout()
来模拟web服务调用延迟:
父组件:
export default function App() {
const [val, setVal] = useState(0);
const doOperation = (qty) => {
setTimeout(() => {
setVal((prev) => prev + qty);
}, 5000);
};
return (
<div className="App">
<input placeholder={val} />
<div style={{ display: "flex" }}>
<ChildButtons qty={1} doOperation={doOperation} />
</div>
</div>
);
}
子组件:
const ChildButtons = ({ qty, doOperation }) => {
const [disabled, setDisabled] = useState(false);
return (
<div>
<button
onClick={() => {
// How can I disable the button prior to call and enable after it.
setDisabled(true);
doOperation(qty);
setDisabled(false);
}}
disabled={disabled}
>
{" "}
+ {qty}
</button>
<button
onClick={() => {
// How can I disable the button prior to call and enable after it.
setDisabled(true);
doOperation(-1 * qty);
setDisabled(false);
}}
disabled={disabled}
>
{" "}
- {qty}
</button>
</div>
);
};
https://codesandbox.io/s/quizzical-easley-7oyeyk
更新:
虽然上面的示例代码只有两对按钮,但可能有任何数量的按钮。我有一个可滚动列表,每个列表项有两个按钮,所以从技术上讲,显示屏上可以有任何数量的按钮。
2条答案
按热度按时间xzlaal3s1#
您必须将状态提升到父组件:
并在孩子体内使用:
7fyelxc52#
你必须“promisify”回调函数,这样你就可以
await
它(至少这是最简单的方法-你也可以用.then
来做到这一点,或者更详细地说,通过将回调传递给它将在主函数之前和之后执行的父函数):父组件:
(so父组件实际上并没有真正改变,我只是将
setTimeout
调用转换为promise,以便在子组件中更容易“等待它们”)。子组件:
(It不清楚第二个子按钮在这里应该做什么。你可以做和第一个按钮一样的事情,尽管在原始代码中你似乎没有尝试这样做,所以我在这里保留了它。看看你对另一个答案的响应,如果你想让第二个按钮独立于第一个按钮被禁用,你当然需要在子组件中有两个单独的状态变量,一个用于每个按钮的
disabled
状态)。