我对 React 很陌生,我遇到了一个问题,当尝试将数组映射到 React 有状态组件列表时,我的所有组件都会丢失其状态。我的代码:
const { useState, useEffect} = React;
const htmlRoot = document.getElementById('root');
const reactRoot = ReactDOM.createRoot(htmlRoot);
const App = () => {
const Item = (props) => {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount((lastCount) => lastCount + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
return <h1>{props.children + ' ' + count}</h1>;
};
const arr = [1, 2, 3];
const [arrState, setArrState] = useState(arr);
const clickHandler = () => {
setArrState((lastArrState) => [
...lastArrState,
lastArrState.at(-1) + 1,
]);
};
return (
// Unfortunately, Stack Snippets don't support the shorthand form
// of fragments
<React.Fragment>
{arrState.map((num, index) => (
<Item key={index}>{num}</Item>
))}
<button onClick={clickHandler}>Click Me</button>
</React.Fragment>
);
};
reactRoot.render(<App />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
他们有可能保持自己的状态吗?如果是的话,怎么样? 更新:
最佳答案
每次调用您的 App
组件进行渲染时,您都会创建一个新 Item
组件。由于后续渲染使用与之前渲染不同的组件,React 会删除之前的实例并创建具有新状态的新实例。
相反,请在 App
外部定义您的 Item
组件,然后在以下位置使用它:
const { useState, useEffect } = React;
const htmlRoot = document.getElementById('root');
const reactRoot = ReactDOM.createRoot(htmlRoot);
const Item = (props) => {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount((lastCount) => lastCount + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
return <h1>{props.children + ' ' + count}</h1>;
};
const App = () => {
const arr = [1, 2, 3];
const [arrState, setArrState] = useState(arr);
const clickHandler = () => {
setArrState((lastArrState) => [
...lastArrState,
lastArrState.at(-1) + 1,
]);
};
return (
// (Sadly, Stack Snippets don't support the shorthand form
// of fragments.)
<React.Fragment>
{arrState.map((num, index) => (
<Item key={index}>{num}</Item>
))}
<button onClick={clickHandler}>Click Me</button>
</React.Fragment>
);
};
reactRoot.render(<App />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
另外,不要使用 index
作为 key
(除非列表是静态的或不断增长且从未重新排序 - 您的列表适合后一类,但我猜测在某个时候你会从中删除项目)。详细原因in the documentation和 the article it links to 。相反,请确保列出的内容具有某种形式的唯一、可重复使用的标识符。
关于javascript - 如何在 react 中创建包含有状态组件的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73837118/