先看段代码:
import {useState, useEffect} from 'react'
function Example() {
const [waitlist, setWaitlist] = useState([]);
const [,forceUpdate] = useState({})
const [num, setNum] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setNum(num + 1)
console.log('id: ' + id + ', num: ' + num)
waitlist.push(Math.random())
setWaitlist(waitlist)
}, 1000);
return () => clearInterval(id)
}, []);
function handleUpdate() {
console.log(waitlist)
forceUpdate({})
}
return (
<div>
<h2>test</h2>
<div><button onClick={forceUpdate}>force</button></div>
<div>{num}</div>
<ol>
{waitlist.map((name) => (
<li key={name}>{name}</li>
))}
</ol>
</div>
)
}
function App() {
return (
<div className="App">
<Example />
</div>
);
}
export default App;
运行结果:控制台输出信息可知 waitlist 数组在不断新增数据项,但view却并未更新; 解决方法,有几种(每种都可单独用):
- setWaitlist(waitlist) 改成 setWaitlist(Array.from(waitlist));
- setNum(num + 1) 改成 setNum(c => c + 1);
- 如上定一个const [,forceUpdate] = useState({}) 专门负责 forceUpdate;
后记,由于React设计哲学是基于函数式编程,组件会被渲染多次,即上面的组件代码(同一个组件)会被执行多次,因此有很多面向对象或基于对象的编程习惯和思想会与之产生冲突,试着接受和习惯就好。