如何避免 React Hook UseState 共享状态?
How to avoid React Hook UseState to share the states?
这个问题的标题可能不好,但这是我的情况。
我使用一大块 json 来呈现列表。如果列表项有 children 属性,则可以展开并显示子列表。 json 结构包括两个数组,每个数组包含更多 sub-arrays。我使用制表符来切换数组。
我使用 useState
来管理每个 sub-array 组件的值 isExpanded
。但似乎状态 isExpaned
为所有选项卡共享。
即使我切换到另一个选项卡,状态 isExpanded
仍然保持不变。换句话说,为什么当我切换到另一个选项卡时 sub-list 一直展开?
另外,为什么每个tab展开的sub-list会相互重叠。当我切换到另一个选项卡时,它们应该保持 'close',因为我已经将初始状态设置为 false
。 (const [isExpand, setIsExpand] = useState(false)
)
const ListItem = ({name, children}) => {
const [subList, setSubList] = useState(null)
const [isExpand, setIsExpand] = useState(false)
const handleItemClick = () => {
children && setIsExpand(!isExpand)
console.log(isExpand)
}
useEffect(() => {
isExpand && children && setSubList(children)
}, [isExpand, children])
return (
<div className='list-wrapper'>
<div className='list-item'>
{name}
{
children &&
<span
className='expand'
onClick={() => handleItemClick()}>
{isExpand ? '-' : '+'}
</span>
}
</div>
<div className='list-children'>
{
isExpand && subList && subList.map((item, index) =>
<ListItem key={index} name={item} />
)
}
</div>
</div>
)
}
这是codesanbox,有人帮忙吗?
似乎 React 因 index
被用作 ListeItem
键而感到困惑。
(React 将尝试 "share" isExpanded
状态,因为它们根据您指定的键看起来相同)
您可以更改密钥 key={index}
<div className="contents">
{contents &&
contents.children &&
contents.children.map((item, index) => (
<ListItem
...... ....
key={index}
name={item.name}
children={item.children}
/>
))}
</div>
要使用更多不同的密钥,item.name
<div className="contents">
{contents &&
contents.children &&
contents.children.map(item => (
<ListItem
...... ....
key={item.name}
name={item.name}
children={item.children}
/>
))}
</div>
这个问题的标题可能不好,但这是我的情况。
我使用一大块 json 来呈现列表。如果列表项有 children 属性,则可以展开并显示子列表。 json 结构包括两个数组,每个数组包含更多 sub-arrays。我使用制表符来切换数组。
我使用 useState
来管理每个 sub-array 组件的值 isExpanded
。但似乎状态 isExpaned
为所有选项卡共享。
即使我切换到另一个选项卡,状态 isExpanded
仍然保持不变。换句话说,为什么当我切换到另一个选项卡时 sub-list 一直展开?
另外,为什么每个tab展开的sub-list会相互重叠。当我切换到另一个选项卡时,它们应该保持 'close',因为我已经将初始状态设置为 false
。 (const [isExpand, setIsExpand] = useState(false)
)
const ListItem = ({name, children}) => {
const [subList, setSubList] = useState(null)
const [isExpand, setIsExpand] = useState(false)
const handleItemClick = () => {
children && setIsExpand(!isExpand)
console.log(isExpand)
}
useEffect(() => {
isExpand && children && setSubList(children)
}, [isExpand, children])
return (
<div className='list-wrapper'>
<div className='list-item'>
{name}
{
children &&
<span
className='expand'
onClick={() => handleItemClick()}>
{isExpand ? '-' : '+'}
</span>
}
</div>
<div className='list-children'>
{
isExpand && subList && subList.map((item, index) =>
<ListItem key={index} name={item} />
)
}
</div>
</div>
)
}
这是codesanbox,有人帮忙吗?
似乎 React 因 index
被用作 ListeItem
键而感到困惑。
(React 将尝试 "share" isExpanded
状态,因为它们根据您指定的键看起来相同)
您可以更改密钥 key={index}
<div className="contents">
{contents &&
contents.children &&
contents.children.map((item, index) => (
<ListItem
...... ....
key={index}
name={item.name}
children={item.children}
/>
))}
</div>
要使用更多不同的密钥,item.name
<div className="contents">
{contents &&
contents.children &&
contents.children.map(item => (
<ListItem
...... ....
key={item.name}
name={item.name}
children={item.children}
/>
))}
</div>