/**https://zhuanlan.zhihu.com/p/92349623
* 执行顺序解析:https://cloud.tencent.com/developer/article/1629182
* 是useState顺序很重要:https://www.cnblogs.com/fengyuqing/p/15074207.html
* useState
* 1 通过多次调用useState拥有多种状态
* 要确保对useState()的多次调用在渲染之间始终保持相同的顺序(后面会讲)。
* 2 状态的延迟初始化
* 每当 React 重新渲染组件时,都会执行useState(initialState)。如果初始状态是原始值(数字,布尔值等),则不会有性能问题。
当初始状态需要昂贵的性能方面的操作时,可以通过为useState(computeInitialState)提供一个函数来使用状态的延迟初始化
* 3 在使用useState() Hook 时,必须遵循 Hook 的规则
仅顶层调用 Hook :不能在循环,条件,嵌套函数等中调用useState()。在多个useState()调用中,渲染之间的调用顺序必须相同。
仅从React 函数调用 Hook:必须仅在函数组件或自定义钩子内部调用useState()。
* 4 过时状态
当闭包捕获过时的状态变量时,就会出现过时状态的问题。可以通过使用一个回调来更新状态来解决这个问题,这个回调会根据先前的状态来计算新的状态。
用setCount(count => count + 1)来替换etCount(count + 1)从而解决问题
* 5 复杂状态管理
对于复杂的状态管理,可以使用useReducer()
* 6 状态和引用
* 7 严格遵守hooks规则,可安装eslint-plugin-react-hooks检查
* 配置:package.json
"eslintConfig":{
"extends":"react-app",
"plugins":[
"react-hooks"
],
"rules":{
"react-hooks/rules-of-hooks":"error"
}
},
*/
import { processPluginHooks } from '@tarojs/runtime';
import React,{useState} from 'react';
let id = 0;
let firstRender = true;
export default function App(){ let initName;
/**这是错误用法 */
if(firstRender){
[initName] = useState("Rudi");
firstRender = false;
}
const [firstName, setFirstName] = useState(initName);
const [lastName, setLastName] = useState("Yardley");
return (
<button onClick={() => setFirstName("Fred")}>Fred</button>
);
}
function App2(){
/**这是错误用法 */
let name , setName;
let count, setCount;
id += 1;
/*if(id & 1){
[count,setCount] = useState(0);
[name,setName] = useState('Mick');
}else{
[name,setName] = useState('Mick');
[count,setCount] = useState(0);
}*/
[count,setCount] = useState(0);
[name,setName] = useState('Mick');
if(id===1){
useState('ss')
}
return(
<button onClick={()=>{setCount(count+1)}}>
Click({count}),name({name})
</button>
)
}
function Bulbs(props){
const [on,setOn] = useState(false);
//const [count,setCount] = useState(1);
//使用延迟初始化
const [count,setCount] = useState(()=>{
//此函数在渲染中只会渲染一次
console.log('initial count');
return props.defaultCount || 0;
})
const [asyCount,setAsyCount] = useState(0);
const handleClickAsync = () =>{
setTimeout(function delay(){
setAsyCount(asyCount + 1);
//正确使用:确保最新状态值作为参数提供给更新状态函数
//setAsyCount(asyCount => asyCount+1)
},1000)
}
const lightSwitch = () =>setOn(!on);
const addBulbs = () => setCount(count => count + 1);
return(
<>
<button onClick={lightSwitch}>on/off:{String(on)}</button>
<button onClick={addBulbs}>add Bulbs:{count}</button>
<button onClick={handleClickAsync}>asy Count:{asyCount}</button>
</>
)
}