javascript - 对父组件的异步函数调用
问题描述
我有这个
const Parent = () => {
[modalOpen, setModal] = React.useState(false);
return <Child
open={modalOpen}
closeModal={() => setModal(false)}
functionFromParent={() => console.log('Logged')} />
}
然后
const Child = ({ functionFromStore, functionFromParent, closeModal }) => {
async function foo() {
try {
await ...;
functionFromStore();
functionFromParent();
} catch (error) {
....
}
}
const bar = () => {
foo();
closeModal();
}
return <div
style={{backgroundColor: 'hotpink', width: '10rem', height: '10rem' }}
onClick={() => bar()}/>
}
零件。
<Parent />
决定是否显示<Child />
(它是Modal)。
<Child />
具有三个功能,closeModal()
和functionFromParent()
,来自<Parent/ >
. 并且functionFromStore()
来自redux
通过dispatchToProps()
。为了简单起见,我把所有的connect(stateToProps, dispatchToProps)(...)
东西都省略了。但是让我们假设<Child />
直接连接到store
.
单击<div />
in<Child/>
执行bar()
。这会导致<Child />
,unmount
因为closeModal()
在<Parent />
被调用时,关闭modal。但是,bar()
也调用foo()
, 作为一个async
函数。
await
解决后,将调用functionFromStore()
,但不调用functionFromParent()
。我想知道这是为什么?为什么一个函数来自被store
调用,即使组件 ( <Child />
) 已卸载,但不是来自父级的函数?
此外,有没有办法调用functionFromParent()
,即使<Child />
已卸载?它以某种方式工作functionFromStore()
,有没有办法让它工作functionFromParent()
?
解决方案
我无法重现您描述的行为,但这可能是一个关闭问题,因为您多次设置状态但在处理程序的关闭中有一个陈旧的状态值
您可以通过将回调传递给 state setter: 来解决它setSomeState(currentState=>({...currentState,changes}))
,这是一个完整的示例:
function Parent() {
const [state, setState] = React.useState({
showModal: true,
showFoo: false,
});
return (
<div>
{state.showModal ? (
<Child
open={state.showModal}
closeModal={() =>
setState(state => ({
...state,
showModal: false,
}))
}
functionFromParent={() =>
setState(state => ({
...state,
showFoo: true,
}))
}
/>
) : (
'Child is gone '
)}
{state.showFoo ? <Foo /> : 'no foo'}
</div>
);
}
function Child({ functionFromParent, closeModal }) {
function foo() {
setTimeout(() => {
functionFromParent();
}, 1000);
}
const bar = () => {
foo();
closeModal();
};
return <button onClick={bar}>click me</button>;
}
function Foo() {
return 'hi, I am Foo';
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
<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="root"></div>
推荐阅读
- cordova - 如何使用 Framework7 Cordova 实时获取推送通知
- scala - scala新类中的“自我”含义是什么
- mysql - 如何获取mysql中IN子句定义的所有项目
- c# - 任务的返回类型错误
- java - 每次更新 maven 时,如何在更新 maven 项目选项中保持“强制更新快照/发布”选项
- c++ - 第二次运行时出错
- android - 将消息从 Oracle 数据库推送到客户端
- vue.js - 无法使用放置在模板数据中的值。只有道具价值有效
- php - Execute PHP script via supervisor in docker
- code-editor - 使用 GEE 代码编辑器从功能中提取的现有列表创建唯一值列表