【发布时间】:2021-02-20 00:50:00
【问题描述】:
我很难理解为什么我在这个 React 组件的控制台中记录了不同的值:
const MyComponent = () => {
// Initialise data with a random value:
const [data, setData] = React.useState(
() => {
const data = _.sampleSize(_.range(5), 3)
// Print data on initialisation:
console.log('init data in default:', data)
return data
}
)
React.useEffect(() => {
// Print data after the component is rendered:
console.log('init data after render:', data)
})
return (
<div>{data}</div>
);
};
控制台的输出是:
[Log] init data in default: – [0, 3, 1] (3)
[Log] init data after render: – [2, 1, 3] (3)
并且组件被渲染到:<div>213</div>
但是为什么值不同呢?
我的理解是在组件渲染之前,调用useState下的函数。函数返回的值赋值给data,data的值用于在屏幕上渲染组件。 useState下的函数只调用一次,我们从不调用setData,所以值应该是一样的。我错过了什么?
UPD:我尝试创建一个代码sn-p,这是我第一次使用codesandbox,所以如果它不起作用请告诉我:
https://codesandbox.io/s/jovial-glade-9jm75?file=/src/App.js
【问题讨论】:
-
这与
<StrictMode>有关。从您的 index.js 中删除它,问题就会消失。但我还没有把所有的部分放在一起给出一个完整的答案。 -
肯定是
StrictMode在工作中,它调用了两次渲染,因此调用了两次useState,由于sampleSize返回随机元素,第二次渲染中的随机选择就是useEffect拾取的. -
嗯,但是为什么
console.log('init data in default:', data)只打印一次呢?我想我至少应该看到React.useState下的函数被调用了两次。 -
React 17,React 会自动修改 console.log() 等控制台方法,以在第二次调用生命周期函数时使日志静音。
标签: javascript reactjs lodash