我正在学习如何使用 Hooks
我正在渲染一个数组列表,删除第一个元素 onclick 状态正在该 handleclick 函数中更新,但未渲染
export default function App() {
const [name, setName] = useState("");
const [arry, setArry] = useState([1, 2, 3, 4, 5]);
const _log = () => {
let ar = arry;
ar.shift();
setArry(ar);
console.log(arry, "log");
};
const renderlist = () => {
console.log(arry, "--");
if (arry.length > 1) {
return arry.map((a) => <li>{a}</li>);
}
}; //
return (
<div className="App">
<button onClick={_log}>shift</button>
{renderlist()}
</div>
);
} ```
答案 0 :(得分:0)
您需要将不同的值(数组)传递给 setArry
。因为 useState
被优化为在 newValue === currValue
时不改变值。
你传递相同的数组是因为你改变了它,这是 React 中的反模式(如你所见)。
const _log = () => {
const [_, ...ar] = arry;
setArry(ar);
// or setArry(([_, ...ar]) => ar);
console.log(arry, "log");
};
答案 1 :(得分:0)
React 通过引用而不是值来比较对象和数组。这意味着 React 正在检查的是分配数组的内存位置,而不是数组的实际内容。只要引用保持不变,React 就不会检测到数组内部所做的任何更改。
let ar = arry;
ar.shift();
setArry(ar);
此处的 ar
变量只不过是指向当前 arry
变量的指针。当您执行 setArry(ar)
时,您所做的是再次将相同的指针分配给您的 arry
值。这就是它不渲染的原因:由于对数组的引用仍然相同,React 不知道您所做的更改。
为了解决这个问题,您需要创建一个包含更改的新数组实例并将其传递给 setArry
。
setArry([...ar]);
这里我们使用解构来创建当前 ar
数组的副本。由于此副本是一个完全不同的元素,因此它具有不同的引用。因此,使用此新项目调用 setArry
将导致您的组件使用新值重新呈现。
答案 2 :(得分:0)
您需要在进行更改之前获取数组的副本,否则您仍将引用原始数组。
let ar = [...arry];
稍微改变你的条件:
if (arry.length > 0) {
// Get a hook function
const {useState} = React;
function Example() {
const [name, setName] = useState("");
const [arry, setArry] = useState([1, 2, 3, 4, 5]);
const _log = () => {
let ar = [...arry];
ar.shift();
setArry(ar);
// console.log(arry, "log");
};
const renderlist = () => {
// console.log(arry, "--");
if (arry.length > 0) {
return arry.map((a) => <li>{a}</li>);
}
}; //
return (
<div className="App">
<button onClick={_log}>shift</button>
{renderlist()}
</div>
);
};
// Render it
ReactDOM.render(
<Example title="Example using Hooks:" />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>