![](/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.