const Parent = ({list}) => {
const closeAll = () => {
// What should be in here?
}
return (
<>
<button onClick={() => closeAll()}>Close All</button>
{list.map(item => <Accordion item={item}/>)}
</>
)
}
const Accordion = ({item}) => {
const [open, setOpen] = useState(false);
return (
<div onClick={() => setOpen(o => !o)}>
<p>item.name</p>
{open && <p>item.detail</p>
</div>
)
}
基本上,如上所述,有Accordion組件和承載所有組件的父組件。每個Accordion組件都有一個名為 的狀態open。我想從父組件更改每個子組件的狀態。如何向子組件發送訂單以更改其狀態?
uj5u.com熱心網友回復:
將您的狀態提升到Parent.
closeAll只需映射串列并將所有open屬性設定為false.- 有一個
handleClick回呼,您傳遞給Accordion它,將單擊專案的open屬性的狀態設定為 inverse inParent - 查看
如果您無法提升狀態,則可以使用 react refs 替代方法。
創建 ref(最初是一個空陣列),
Accordion當它第一次渲染時,每個都會將自己的關閉狀態設定函式推入。在 中
Parent,回圈遍歷 ref 中的關閉狀態設定函式陣列并執行每個函式。const Parent = ({ list = data }) => { const myRef = useRef([]); const closeAll = () => { myRef.current.forEach((c) => c()); }; return ( <> <button onClick={() => closeAll()}>Close All</button> {list.map((item, i) => ( <Accordion item={item} myRef={myRef} /> ))} </> ); }; const Accordion = ({ item, myRef }) => { const [open, setOpen] = useState(false); useEffect(() => { myRef.current.push(() => setOpen(false)); }, [myRef]); return ( <div> <button onClick={() => setOpen((o) => !o)}>{item.name}</button> {open && <p>{item.detail}</p>} </div> ); }; export default Parent;uj5u.com熱心網友回復:
不建議為組件使用內部狀態,至??少從我的角度來看您正在做什么。
您可以從其屬性中控制每個串列項的打開狀態,例如此處的示例:
const Parent = ({ list }) => { const [isAllClosed, setIsAllClosed] = useState(false); const closeAll = () => { setIsAllClosed(true) }; return ( <> <button onClick={closeAll}>Close All</button> {list.map((item) => ( item.open = isAllClosed != null ? (!isAllClosed) : true; <Accordion item={item} /> ))} </> ); }; const Accordion = ({ item }) => { return ( <div onClick={() => console.log('item clicked')}> <p>item.name</p> {item.open ? <p>item.detail</p> : null} </div> ); };我也把你的短路評估換成
open && <p>item.detail</p>了三元。這樣做的原因是false如果不是真的,你會得到一個被列印的字串,這有意義嗎?您將需要以某種方式控制整個串列的狀態,無論專案是否從使用父項的人那里打開。
但是盡可能避免使用內部狀態。
uj5u.com熱心網友回復:
我認為您可以嘗試在父級內部創建一個狀態變數并將其作為道具傳遞給子級以控制子級的行為。
const Parent = ({ list }) => { const [masterOpen, setMasterOpen] = useState(true); <> <button onClick={() => setMasterOpen(false)}>Close All</button> {list.map((item) => ( <Accordion item={item} parentOpen={masterOpen} /> ))} </> ); }; const Accordion = ({ item, parentOpen }) => { const [open, setOpen] = useState(false); if (!parentOpen) { setOpen(false); } return ( <div onClick={() => setOpen((o) => !o)}> <p>{item.name}</p> {open && <p>item.detail</p>} </div> ); };
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/365435.html標籤:javascript 反应
