Javascript 为什么在渲染后更新functional React组件中的默认值?
我很难理解为什么控制台中会记录此React组件中的不同值:Javascript 为什么在渲染后更新functional React组件中的默认值?,javascript,reactjs,lodash,Javascript,Reactjs,Lodash,我很难理解为什么控制台中会记录此React组件中的不同值: const MyComponent = () => { // Initialise data with a random value: const [data, setData] = React.useState( () => { const data = _.sampleSize(_.range(5), 3) // Print data on initialisation:
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>
);
};
组件被渲染到:213
但为什么价值观不同呢
我的理解是,在呈现组件之前,将调用useState
下的函数。函数返回的值分配给数据
,而数据
值用于在屏幕上呈现组件。useState
下的函数只调用一次,我们从不调用setData
,因此值应该相同。我错过了什么
UPD:我试图创建一个代码段,这是我第一次使用codesandbox
,因此如果它不起作用,请告诉我:
导致对运行组件进行两次响应,以检测各种可能的不安全代码段。这有点像有限的运行时过梁
其中:
从React 17开始,React自动修改console方法,如console.log(),以便在第二次调用lifecycle函数时使日志静音 第一次调用组件时,运行
useState
调用中的console.log
,记录生成的第一个数据
第一次调用没有完全呈现;useffect
从不运行。相反,React会再次运行组件以检查不一致性。在第二次运行时,useState
中的console.log
被抑制
然后,在第二次运行时,组件真正正确地完成渲染,并运行其效果挂钩,该挂钩记录以前生成的数据(但未显示在控制台中)
.这与
有关。将其从index.js中删除,问题就会消失。但是我还没有把所有的部分放在一起给出一个完整的答案。显然,StrictMode
在工作时,它会调用render两次,从而调用useState
两次,因为sampleSize
返回随机元素,所以第二次渲染中的随机选择是由useffect
拾取的,但是为什么console.log('init data in default:',data)
只打印一次?我想我至少应该看到,React.useState
下的函数被调用了两次。React 17,React自动修改控制台方法,如console.log(),以便在对生命周期函数的第二次调用中使日志静音。好的,谜团就解决了。但这是相当出乎意料的行为。您看不到组件被重新渲染,并且输出不同。很高兴知道!谢谢你的详细回答
[Log] init data in default: – [0, 3, 1] (3)
[Log] init data after render: – [2, 1, 3] (3)