我正在尝试将业务逻辑的某些部分与视图逻辑分开,为此我正在使用自定义反应挂钩,其工作原理类似于控制器。
我的组件结构
为什么我无论花多长时间都看不到child 2内的页面正在加载
我相信当子 2 上再次调用自定义钩子时,useState 将标志设置为其默认 false
我必须如何在自定义反应钩子中使用 useState 钩子,该钩子从多个地方调用并且不将状态恢复为默认值
如果您打开 child2,flag 永远不会为 true
这是codesandbox链接代码
这是代码
App.js 作为父级
import "./styles.css";
import Child1 from "./Child1";
import Child2 from "./Child2";
import { useEffect, useState } from "react";
import useCustomHook from "./customHook";
import { makeStyles } from "@material-ui/core";
const useStyles = makeStyles((theme) => {
return {
parent: {
padding: "10px"
},
toggle: {
margin: "10px",
border: "1px solid black",
display: "flex",
justifyContent: "space-around"
},
child: {
border: "1px solid black",
width: "50%"
}
};
});
export default function App() {
const [isChild1, setIsChild1] = useState(true);
const classes = useStyles();
const { flag, func } = useCustomHook();
useEffect(() => {
func();
}, []);
return (
<div className="App">
<div className={classes.parent}>Parent</div>
<div className={classes.toggle}>
<div
onClick={() => {
setIsChild1(true);
}}
className={classes.child}
>
ch1
</div>
<div
onClick={() => {
setIsChild1(false);
}}
className={classes.child}
>
ch2
</div>
</div>
{isChild1 ? <Child1 /> : <Child2 />}
</div>
);
}
Child1.js
const Child1 = () => {
return <div>Child1</div>;
};
export default Child1;
Child2.js
import useCustomHook from "./customHook";
const Child2 = () => {
const { flag } = useCustomHook();
console.log('flag ',flag);
return (
<div>
<div>Child2</div>
<div>{flag ? "loading..." : "content"}</div>
</div>
);
};
export default Child2;
自定义Hook.js
import { useState } from "react";
const useCustomHook = () => {
const [flag, setFlag] = useState(false);
const sleep = async (ms) => {
console.log("waiting");
await new Promise((res, rej) => {
setTimeout(() => {
console.log("wait over");
}, ms);
});
};
const func = async () => {
setFlag(true);
//do some work like api call
await sleep(10000);
setFlag(false);
};
return { flag, func };
};
export default useCustomHook;
如果你从App和Child2调用
useCustomHook
,你会得到两个不同的对象!
useCustomHook
和 func
,flag
从 App 传递到 Child2(使用 props 或 context)顺便说一句。在
sleep
函数中,您忘记了解决承诺。
const sleep = async (ms) => {
console.log("waiting");
await new Promise((res, rej) => {
setTimeout(() => {
console.log("wait over");
res(); // important!
}, ms);
});
};