为什么顺序对React Hooks很重要

#积累/react/react-hooks#

1
2
3
4
5
6
7
8
function RenderFunctionComponent() {
const [firstName, setFirstName] = useState("Rudi");
const [lastName, setLastName] = useState("Yardley");

return (
<Button onClick={() => setFirstName("Fred")}>Fred</Button>
);
}
  • 在实际执行过程中。useState状态数据不会被其他组件共享,但是会存储在组件的外部,为了能够在随后的组件渲染中访问到。

Hook执行顺序

  • 初始化
    创建两个空数组,setters和state
    设置一个指向0的指针
  • RenderFunctionComponent组件初次渲染
    每调用一次useState(),state推进一个状态,setters推进一个setter函数
  • RenderFunctionComponent再次渲染
    指针被重置,分别读取state中的值
  • 事件处理
    setter与state由同一个指针关联起来,调用setter会改变相应指针下的state

useState错误的调用顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
let firstRender = true;
function RenderFunctionComponent() {
let initName;
if(firstRender){ //在条件中调用useState
[initName] = useState("Rudi");
firstRender = false;
}
const [firstName, setFirstName] = useState(initName);
const [lastName, setLastName] = useState("Yardley");
return (
<Button onClick={() => setFirstName("Fred")}>Fred</Button>
);
}
  • 第一次渲染
  • 第二次渲染
  • 回到React Hooks原则
    不在循环,条件或嵌套函数中调用Hook的原则,保证hooks的调用在最顶层,才能够保证函数组件再次渲染的时候,state数据的一致性。

React hooks: not magic, just arrays - Rudi Yardley - Medium