[英]How to avoid re-render of React Hooks
嗨,我是 ReactJs 的新開發人員。 我有一個關於 Hooks 的問題。 我知道關於這個任務有很多答案,但我沒有將這些解決方案集成到我的項目中。 我有父子組件。 我正在將價值從孩子傳遞給父母。 當我嘗試通過反應回調 function 發送數據時,父級在獲取項目時重新渲染,因此我在子級上丟失了我選擇的值。 我該如何保護這些問題? 你能給我什么建議嗎?
父組件:
import React,{useCallback,useState} from 'react'
const Dropable = ({item}) => {
const [list, setList] = useState(item)
const [selectedItems, setSelectedItems] = useState<Array<any>>([])
const handleSelectedItems = useCallback( (data: any) => {
if (data.type === "player") {
if (selectedItems.length === 0) {
const arr = selectedItems
arr.push(data)
setSelectedItems(arr)
}
}, [selectedItems],
)
return (
{list.map((data: any, index: any) => {
return (
<>
{
<div onClick={() => handleSelectedItems(index, data)}>
<Detailed
key={uuid()}
data={data}
dataIndex={index}
/>
</div>
}
</>
)
})}
)
}
export default Dropable;
子組件:
import React,{useState} from 'react'
const Detailed : React.FC<IProps> = (props) {
const [selected, setSelected] = useState(false)
const handleSelect = () => {
if (selected) {
setSelected(false)
}
else {
setSelected(true)
}
}
return (
<div onClick={handleSelect} className="detail" style={selected?{border: " 1px solid #5c6ef5"}: {}}>
</div>
)
}
export default Detailed;
您可以簡單地將selected
的值從父組件傳遞給子組件,並使用該道具啟動選定的 state。
const [selected, setSelected] = useState(props.selected)
那么每次父更新,子選擇的state就不會是null了。 您可以通過 null 作為通過道具選擇的初始值。 所以,你會這樣調用子組件,
import React,{useCallback,useState} from 'react'
const Dropable = ({item}) => {
const [list, setList] = useState(item)
const [selectedItems, setSelectedItems] = useState<Array<any>>([])
const handleSelectedItems = useCallback( (data: any) => {
if (data.type === "player") {
if (selectedItems.length === 0) {
const arr = selectedItems
arr.push(data)
setSelectedItems(arr)
}
}, [selectedItems],
)
return (
{list.map((data: any, index: any) => {
const isSelected = selectedItems.findIndex(item => item.[some_unique_attribute] === data.[some_unique_attribute]) > -1;
return (
<>
{
<div onClick={() => handleSelectedItems(index, data)}>
<Detailed
key={uuid()}
data={data}
dataIndex={index}
selected={isSelected}
/>
</div>
}
</>
)
})}
)
}
嗨,您可以將該值從父級傳遞給子級,而不是在子級中維護 boolean 值以查看該項目是否被選中。 所以父組件:
const Dropable = ({ item }) => {
const [list, setList] = useState(item)
const [selectedItems, setSelectedItems] = useState<Array<any>>([])
const handleSelectedItems = useCallback((data: any) => {
if (data.type === "player") {
if (selectedItems.length === 0) {
const arr = selectedItems
arr.push(data)
setSelectedItems(arr)
}
}, [selectedItems],
)
return (
{
list.map((data: any, index: any) => {
return (
<>
{
<div onClick={() => handleSelectedItems(index, data)}>
<Detailed
key={uuid()}
data={data}
dataIndex={index}
selected={selectedItems[0][ANY_KEY] === data[ANY_key]}
/>
</div>
}
</>
)
})
}
)
}
export default Dropable;
還有你的子組件:不需要使用 useState 來設置值,因為我們在父組件中做同樣的工作。
import React,{useState} from 'react'
const Detailed : React.FC<IProps> = (props) {
return (
<div className="detail" style={props.selected?{border: " 1px solid
#5c6ef5"}: {}}>
</div>
)
}
export default Detailed;
另一個提示:將數據從子組件發送到父組件不是一個好習慣。
當父級重新渲染時,您的子級丟失其 state 的唯一原因是因為您在映射時為子組件分配了一個新鍵
分配一個唯一但在重新渲染時保持相同的鍵將防止此問題發生
如果組件的鍵發生變化,它不會重新渲染而是重新安裝,因此 state 值被重置
如果數據中沒有唯一鍵,您可以使用a unique value as key from data
或替代使用index
。 但是,您必須嘗試在數據中至少包含 1 個可用於唯一標識它的字段
return (
{
list.map((data: any, index: any) => {
return (
<>
{
<div onClick={() => handleSelectedItems(index, data)}>
<Detailed
key={data.id} // if no id field. You can assign index
data={data}
dataIndex={index}
selected={selectedItems[0][ANY_KEY] === data[ANY_key]}
/>
</div>
}
</>
)
})
}
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.