在 React 中使用 useState 映射外部数组后如何 Show/Hide 嵌套数组 element/component?
How to Show/Hide nested array element/component after mapping outer array with useState in React?
初始objective:
- 我有4个组件,当点击其中一个组件时,其他三个组件消失,只显示被点击的组件。再次单击该组件会切换所有组件以再次显示。
- 我的目标是向数组中的每个组件添加一个 info/description 对象,这样当一个组件被切换时,其他组件仍然消失,但现在根据切换的组件显示描述.
- 我的想法是为描述元素设置可见性标志,将其设置为 false,切换特定组件会将标志更改为 true 并显示描述。
这是我目前的看法:
const array = [
{ id: 1, component: <Comp1/>, isVisible: true,
info: [{ id: 5, component: <div>info1</div>, isVisibleInfo: false }] },
{ id: 2, component: <Comp2/>, isVisible: true,
info: [{ id: 6, component: <div>info2</div>, isVisibleInfo: false }] },
{ id: 3, component: <Comp3/>, isVisible: true,
info: [{ id: 7, component: <div>info3</div>, isVisibleInfo: false }] },
{ id: 4, component: <Comp4/>, isVisible: true,
info: [{ id: 8, component: <div>info4</div>, isVisibleInfo: false }] }
];
export const Test = () => {
const [items, setItems] = useState(array);
const handleClick = (number) => {
const triggeredItems = items.map((item) => {
if (item.id !== number) {
item.isVisible = !item.isVisible;
}
return item;
});
setItems(triggeredItems);
};
const handleClickInner = (number) => {
const triggeredItemsInner = items.info.map((item) => {
if (item.id !== number) {
item.isVisibleInfo = !item.isVisibleInfo;
}
return item;
});
setItems(triggeredItemsInner);
};
return (
<div className="mt-1 pt-1 pb-3 px-3">
<div className="row text-center d-flex my-1">
{items.map(({ id, component, isVisible, info }) => (
<div
key={id}
className="col-lg-3 col-md-6 mb-4 justify-content-center"
onClick={() => handleClick(id)}
hidden={!isVisible}
>
{ component }
{info.map(({ id, component, isVisibleInfo }) => (
<div
key={id}
className="col-lg-9 col-md-6 mb-4 justify-content-center"
onClick={() => { handleClickInner(id)}}
hidden={isVisibleInfo}
>
{ component }
</div>
))}
</div>
))}
</div>
</div>
);
};
export default Test;
目前,我收到此输出 TypeError: Cannot read 属性 'map' of undefined in the 'handleClickInner function 因为我相信 map 无法映射嵌套数组,但总的来说我是甚至不确定创建第二个函数是否是正确的方法。
仍在学习很多关于 React 及其方法的知识!
如有任何想法或帮助,我们将不胜感激!
My goal is to add an info/description object to each of the components
in the array so that when a component is toggled, the other components
still disappear but now a description shows up in accordance with the
toggled component.
你真的不是说消失吗?听起来更像是您想有条件地渲染组件。
已更新
我误会你的意思了!现在他们消失了。
// hooks
const {useState} = React;
function Comp1(){
return <div><p>Component 1</p></div>
}
function Comp2(){
return <div><p>Component 2</p></div>
}
function Comp3(){
return <div><p>Component 3</p></div>
}
function Comp4(){
return <div><p>Component 4</p></div>
}
const array = [
{ id: 1, component: <Comp1/>, isVisible: true,
info: { id: 5, component: <div>info1</div>, isVisibleInfo: false } },
{ id: 2, component: <Comp2/>, isVisible: true,
info: { id: 6, component: <div>info2</div>, isVisibleInfo: false } },
{ id: 3, component: <Comp3/>, isVisible: true,
info: { id: 7, component: <div>info3</div>, isVisibleInfo: false } },
{ id: 4, component: <Comp4/>, isVisible: true,
info: { id: 8, component: <div>info4</div>, isVisibleInfo: false } }
];
const Test = () => {
const [items, setItems] = useState(array);
const handleClick = (number) => {
const triggeredItems = items.map((item) => {
if (item.id !== number) {
item.isVisible = !item.isVisible;
}
item.info.isVisibleInfo =! item.info.isVisibleInfo
return item;
});
setItems(triggeredItems);
};
return (
<div className="mt-1 pt-1 pb-3 px-3">
<div className="row text-center d-flex my-1">
{items.map(({ id, component, isVisible, info }) => (
isVisible ?
<div
key={id}
className="col-lg-3 col-md-6 mb-4 justify-content-center"
onClick={() => handleClick(id)}
hidden={!isVisible}
>
{ component }
{info.isVisibleInfo ?
<div
key={info.id}
className="col-lg-9 col-md-6 mb-4 justify-content-center"
>
{ info.component }
</div>
: null}
</div>
: null
))}
</div>
</div>
);
};
function App(){
return (
<div>
<Test />
</div>
);
};
// Render
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
初始objective:
- 我有4个组件,当点击其中一个组件时,其他三个组件消失,只显示被点击的组件。再次单击该组件会切换所有组件以再次显示。
- 我的目标是向数组中的每个组件添加一个 info/description 对象,这样当一个组件被切换时,其他组件仍然消失,但现在根据切换的组件显示描述.
- 我的想法是为描述元素设置可见性标志,将其设置为 false,切换特定组件会将标志更改为 true 并显示描述。 这是我目前的看法:
const array = [
{ id: 1, component: <Comp1/>, isVisible: true,
info: [{ id: 5, component: <div>info1</div>, isVisibleInfo: false }] },
{ id: 2, component: <Comp2/>, isVisible: true,
info: [{ id: 6, component: <div>info2</div>, isVisibleInfo: false }] },
{ id: 3, component: <Comp3/>, isVisible: true,
info: [{ id: 7, component: <div>info3</div>, isVisibleInfo: false }] },
{ id: 4, component: <Comp4/>, isVisible: true,
info: [{ id: 8, component: <div>info4</div>, isVisibleInfo: false }] }
];
export const Test = () => {
const [items, setItems] = useState(array);
const handleClick = (number) => {
const triggeredItems = items.map((item) => {
if (item.id !== number) {
item.isVisible = !item.isVisible;
}
return item;
});
setItems(triggeredItems);
};
const handleClickInner = (number) => {
const triggeredItemsInner = items.info.map((item) => {
if (item.id !== number) {
item.isVisibleInfo = !item.isVisibleInfo;
}
return item;
});
setItems(triggeredItemsInner);
};
return (
<div className="mt-1 pt-1 pb-3 px-3">
<div className="row text-center d-flex my-1">
{items.map(({ id, component, isVisible, info }) => (
<div
key={id}
className="col-lg-3 col-md-6 mb-4 justify-content-center"
onClick={() => handleClick(id)}
hidden={!isVisible}
>
{ component }
{info.map(({ id, component, isVisibleInfo }) => (
<div
key={id}
className="col-lg-9 col-md-6 mb-4 justify-content-center"
onClick={() => { handleClickInner(id)}}
hidden={isVisibleInfo}
>
{ component }
</div>
))}
</div>
))}
</div>
</div>
);
};
export default Test;
目前,我收到此输出 TypeError: Cannot read 属性 'map' of undefined in the 'handleClickInner function 因为我相信 map 无法映射嵌套数组,但总的来说我是甚至不确定创建第二个函数是否是正确的方法。
仍在学习很多关于 React 及其方法的知识!
如有任何想法或帮助,我们将不胜感激!
My goal is to add an info/description object to each of the components in the array so that when a component is toggled, the other components still disappear but now a description shows up in accordance with the toggled component.
你真的不是说消失吗?听起来更像是您想有条件地渲染组件。
已更新
我误会你的意思了!现在他们消失了。
// hooks
const {useState} = React;
function Comp1(){
return <div><p>Component 1</p></div>
}
function Comp2(){
return <div><p>Component 2</p></div>
}
function Comp3(){
return <div><p>Component 3</p></div>
}
function Comp4(){
return <div><p>Component 4</p></div>
}
const array = [
{ id: 1, component: <Comp1/>, isVisible: true,
info: { id: 5, component: <div>info1</div>, isVisibleInfo: false } },
{ id: 2, component: <Comp2/>, isVisible: true,
info: { id: 6, component: <div>info2</div>, isVisibleInfo: false } },
{ id: 3, component: <Comp3/>, isVisible: true,
info: { id: 7, component: <div>info3</div>, isVisibleInfo: false } },
{ id: 4, component: <Comp4/>, isVisible: true,
info: { id: 8, component: <div>info4</div>, isVisibleInfo: false } }
];
const Test = () => {
const [items, setItems] = useState(array);
const handleClick = (number) => {
const triggeredItems = items.map((item) => {
if (item.id !== number) {
item.isVisible = !item.isVisible;
}
item.info.isVisibleInfo =! item.info.isVisibleInfo
return item;
});
setItems(triggeredItems);
};
return (
<div className="mt-1 pt-1 pb-3 px-3">
<div className="row text-center d-flex my-1">
{items.map(({ id, component, isVisible, info }) => (
isVisible ?
<div
key={id}
className="col-lg-3 col-md-6 mb-4 justify-content-center"
onClick={() => handleClick(id)}
hidden={!isVisible}
>
{ component }
{info.isVisibleInfo ?
<div
key={info.id}
className="col-lg-9 col-md-6 mb-4 justify-content-center"
>
{ info.component }
</div>
: null}
</div>
: null
))}
</div>
</div>
);
};
function App(){
return (
<div>
<Test />
</div>
);
};
// Render
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>