![](/img/trans.png)
[英]When to update state based on previous state in useState hook in React/Typescript
[英]How to refactor an if else if with previous state when using useState Hook?
我有 2 个details
标签,每个标签都有一个控件来打开/关闭它。 代码片段在这里。 单击控件 A 应打开/关闭页面 A,单击控件 B 应打开/关闭页面 B。
我是用一个if else if
plus 2 useState
的,当有多个details
时这是不可行的。 我如何重构代码,以便可以避免if else if
并以更聪明的方式检测我单击的控件?
页面.js
const Page = ({ name, isOpen, setIsOpen }) => {
return (
<>
<details
open={isOpen}
onToggle={(e) => {
setIsOpen(e.target.open);
}}
>
<summary>Page {name} title</summary>
<div>Page {name} contents</div>
</details>
</>
);
};
export default Page;
控件.js
const Control = ({ toggle }) => {
return (
<>
<a onClick={() => toggle("A")} href="#/">
Control A
</a>
<br />
<a onClick={() => toggle("B")} href="#/">
Control B
</a>
</>
);
};
应用程序.js
export default function App() {
const [isOpenA, setIsOpenA] = useState(false);
const [isOpenB, setIsOpenB] = useState(false);
const toggle = (name) => {
if (name === "A") {
setIsOpenA((prevState) => !prevState);
} else if (name === "B") {
setIsOpenB((prevState) => !prevState);
}
};
return (
<div className="App">
<Control toggle={toggle} />
<Page name={"A"} isOpen={isOpenA} setIsOpen={setIsOpenA} />
<Page name={"B"} isOpen={isOpenB} setIsOpen={setIsOpenB} />
</div>
);
}
您可以使用数组来表示开放的
const [openPages, setOpenPages] = useState([])
并切换过滤数组
const toggle = (name) => {
if(openPages.includes(name)){
setOpenPages(openPages.filter(o=>o!=name))
}else{
setOpenPages(pages=>{ return [...pages,name]}
}
}
我个人会使用 object 作为 map 作为你的切换,就像这样:
const [isOpen, _setIsOpen] = useState({});
const setIsOpen = (pageName,value) => _setIsOpen({
...isOpen,
[pageName]: value
});
const toggle = (name) => setIsOpen(name, !isOpen[name]);
然后在模板部分:
<Page name={"A"} isOpen={isOpen["A"]} setIsOpen={toggle("A")} />
通过这种方式,您可以拥有任意数量的切换开关并以任何您想要的方式使用它们
我认为这会更清晰,您还应该将各种页面名称放在一个数组中并像在
const pageNames = ["A","B"];
{
pageNames.map( name =>
<Page name={name} isOpen={isOpen[name]} setIsOpen={toggle(name)} />)
}
至少我是这样想的 go
Adithya 的回答对我有用。
为了将来参考,我把完整的工作代码放在这里。 不需要Page.js
中的onToggle
属性。 所需要的只是将正确true/false
传递给Page.js
中的open={isOpen}
。
应用程序.js:
export default function App() {
const [openPages, setOpenPages] = useState([]);
const toggle = (name) => {
if (openPages.includes(name)) {
setOpenPages(openPages.filter((o) => o !== name));
} else {
setOpenPages((pages) => {
return [...pages, name];
});
}
};
return (
<div className="App">
<Control toggle={toggle} />
<Page name={"A"} isOpen={openPages.includes("A")} />
<Page name={"B"} isOpen={openPages.includes("B")} />
<Page name={"C"} isOpen={openPages.includes("C")} />
</div>
);
}
页面.js
const Page = ({ name, isOpen }) => {
return (
<>
<details open={isOpen}>
<summary>Page {name} title</summary>
<div>Page {name} contents</div>
</details>
</>
);
};
Control.js 保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.