import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,无论何时setCount(count + 1)调用都会发生重新渲染.我很想学习这个流程.
我试着查看源代码.我useState在github.com/facebook/react找不到任何引用或其他钩子.
我安装了react@nextvia npm i react@next,发现了以下内容node_modules/react/cjs/react.development.js
function useState(initialState) {
var dispatcher = resolveDispatcher();
return dispatcher.useState(initialState);
}
Run Code Online (Sandbox Code Playgroud)
在追溯时dispatcher.useState(),我只能找到以下内容......
function resolveDispatcher() {
var dispatcher = ReactCurrentOwner.currentDispatcher;
!(dispatcher !== null) ? invariant(false, 'Hooks can only be …Run Code Online (Sandbox Code Playgroud) 如果我们用相同的值设置状态组件将不会重新渲染,但当我在函数体中设置状态时它不适用。
例如,如果我在按钮单击和单击按钮上设置相同的状态,则组件不会在按钮单击时重新渲染
function Test1() {
const [name, setName] = useState("Shiva");
const onButtonClick = () => {
console.log("Clicked");
setName("Shiva");
};
console.log("Redering");
return (
<div>
<span>My name is {name}</span>
<button onClick={onButtonClick}>Click Me</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
But, when I set the same state before the return statement React goes infinite renderings
function Test2() {
const [name, setName] = useState("Shiva");
// ... come stuff
setName("Shiva");
console.log("Rendering");
return (
<div>
<span>My name is {name}</span>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
What actually happening internally?
下面的代码不应该触发重新渲染,因为它传递了相同的初始值,对吧?但它反而会导致“重新渲染次数过多”错误。
function Test() {
const [counter, setCounter] = useState(0)
setCounter(0)
return <></>
}
Run Code Online (Sandbox Code Playgroud)
编辑:如果您在函数中 setCounter(0) 并将其附加到按钮单击,它不会触发重新渲染,因为它具有相同的值,那么为什么当放置在组件主体中时它会触发重新渲染?我知道 useEffect 具有空依赖数组以避免无限循环。
如果你这样做,你会发现它不会重新渲染:
function Test() {
const [counter, setCounter] = useState(0)
console.log('render');
const set = () => {
setCounter(0)
};
return <button onClick={set}>Set</button>
}
Run Code Online (Sandbox Code Playgroud)