我在尝试 React 切换显示隐藏时遇到了问题。
我用 map 函数调用了我的数组。然后我用切换功能做了打开隐藏的情况,但问题从这里开始。只要我点击任何项目,整个数组就会显示和隐藏。
我在这里做错了什么?我只想查看我单击的项目的隐藏显示状态,但所有这些都已列出。
我的代码:
forfiles /P Downloads /S /D +12/04/2021
我的示例文件:CodeSandbox
答案 0 :(得分:0)
目前状态布尔值对所有项目都是通用的。
您可以创建一个具有自己本地 show
状态的项目组件。
如果您不想创建子组件,您可以使用一个映射,其键是项目 id
,因为状态和值是布尔值 show
沙盒:https://codesandbox.io/s/toggle-example-forked-ijt82?file=/src/App.js
答案 1 :(得分:0)
您对所有商品使用相同的展示价值。当它为一个设置真值时,它会改变所有。
答案 2 :(得分:0)
我稍微修改了您的 CodeSandbox 以拥有 <List />
一个单独的组件,该组件具有自己的 show/hide
状态
const List = (item) => {
const [show, setShow] = useState(false);
const toggleHandler = () => {
setShow(!show);
};
return (
<>
<div onClick={toggleHandler}>
<p style={{ margin: 0, fontWeight: "bold" }}>
{`${item.year} - Total: `} <span>{item.price}</span>
</p>
</div>
{show ? <div>{item.monthlyInstallment}</div> : ""}
</>
);
};
export default function App() {
return (
<div className="App">
{example.map((item) => (<List key={item.id} {...item} />))}
</div>
);
}
答案 3 :(得分:0)
这是因为数组中的每一项都使用 show
状态,您可以做的是为每一项设置一个显示状态,这可以通过多种方式完成,但最干净的方法是将item 在它自己的组件上并赋予它自己的状态。
const Item = ({ item }) => {
const [show, setShow] = useState(false);
const toggleHandler = () => {
setShow(!show);
};
return
<>
<div onClick={toggleHandler}>
<p style={{ margin: 0, fontWeight: "bold" }}>
{`${item.year} - Total: `} <span>{item.price}</span>
</p>
</div>
{show ? <div>{item.monthlyInstallment}</div> : ""}
</>
}
export default function App() {
return (
<div className="App">
{example.map((item) => <Item item={item} />)}
</div>
);
}
答案 4 :(得分:0)
您只有一种状态,其中只能包含 true
或 false
,因此 React 无法知道显示的是哪个项目或您的列表。
一个解决方案是创建一个为每个“项目”呈现的组件:
export default function App() {
return (
<div className="App">
{example.map((item) => (
<Test key={item.id} item={item} />
))}
</div>
);
}
function Test({ item }) {
const [show, setShow] = useState(false);
const toggleHandler = () => {
setShow(!show);
};
return (
<>
<div onClick={toggleHandler}>
<p style={{ margin: 0, fontWeight: "bold" }}>
{`${item.year} - Total: `} <span>{item.price}</span>
</p>
</div>
{show ? <div>{item.monthlyInstallment}</div> : ""}
</>
);
}
答案 5 :(得分:0)
一旦您将 show
设置为 true
,在下一次渲染中所有项目的 show
将是 true
,因此您会看到所有项目。您需要缩小展示逻辑的范围。
您可以做的修复是:
将被点击的项目的 id
传递给 togglerHandler
。
如果 show
不等于传递的 id
,请将 show
设置为传递的 id
。
如果 show
已经等于传递的 id
,请将 show
设置为 null
。
现在在渲染 monthlyInstallment
时只检查是否 show === item.id
,如果它显示 div
,否则不显示。
const {useState} = React;
const example = [
{
id: "1",
year: "2021",
price: 300,
monthlyInstallment: 582.5
},
{
id: "2",
year: 2022,
price: 400,
monthlyInstallment: 500.5
},
{
id: "3",
year: "2023",
price: 500,
monthlyInstallment: 421.5
},
{
id: "4",
year: "2024",
price: 600,
monthlyInstallment: 365.5
},
{
id: "5",
year: "2025",
price: "700$",
monthlyInstallment: 312.5
}
];
function App() {
const [show, setShow] = useState(null);
const toggleHandler = (id) => {
(id === show) ? setShow(null): setShow(id)
};
return (
<div>
{example.map((item) => (
<div key={item.id}>
<div onClick={() => toggleHandler(item.id)}>
<p style={{ margin: 0, fontWeight: "bold" }}>
{`${item.year} - Total: `} <span>{item.price}</span>
</p>
</div>
{show === item.id ? <div>{item.monthlyInstallment}</div> : ""}
</div>
))}
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id="react"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>