1.useState返回的是什么?
返回一个数组!!!
const [state, setState] = useState(intialValue) 数组解构形式而已
数组的第一项是:state
数组的第二项是:setState
2.状态更新变化后,react会重新渲染组件。
导致react一直在重复渲染。
场景: 计算react渲染组件的次数
-
错误写法:
const [state, setstate] = useState(0) useEffect(() => { setstate(state => state + 1) })
state发生改变,组件重新渲染;组件渲染,state发生改变。 导致死循环
-
正确写法 :
使用ref来保存数据,ref保存的数据在发生变化时不会导致组件重新渲染 const timeRef = useRef(1) useEffect(() => { timeRef.current++ })
3.react每次重新渲染组件,都会执行useState
所以如果useState初始状态是原始值(数字,布尔值等),则不会有性能问题。当初始状态需要昂贵的性能方面的操作时,可以通过为useState(computeInitialState)提供一个函数来使用状态的延迟初始化。
const [state, setstate] = useState(()=>{
//TODO: 对数据进行消耗性能的计算,比如JSON.parse
let newValue = JSON.parse(bigData)
return newValue
})
4.useState更新状态的方式,或者说setState()中可以传的值是什么方式
(1)setState(value) : 用值来更新
(2)用回调函数来更新
setState((state)=>{
//TODO:对state进行操作,比如state+1
let newState = state + 1
return newState
})
5.useState状态的延时更新
闭包(例如事件处理程序,回调)可能会从函数组件作用域中捕获状态变量。由于状态变量在渲染之间变化,因此闭包应捕获具有最新状态值的变量。否则,如果闭包捕获了过时的状态值,则可能会遇到过时的状态问题。
const [state, setstate] = useState(0)
const handleClick = () => {
setTimeout(() => {
setstate(state + 1)
}, 2000);
}
state是一个过时的变量
为了解决这个问题,使用函数方法来更新count状态:
const [state, setstate] = useState(0)
const handleClick = () => {
setTimeout(() => {
setstate(state => state + 1)
}, 2000);
}
6.自己实现一个useState
let state:any ;
const useState = (initialValue:any) => {
state = state ===undefined ? initialValue : state
const setstate = (newValue:any) => {
state = newValue
render()
}
return [state, setstate]
}
const render = () => {
ReactDOM.render(<Home />, document.getElementsById('app'));
}
一个组件中可能会有多个useState
let state: any = [];
let index = 0;
const myUseState = (initialValue: any) => {
let renderIndex = index
state[renderIndex] = state[renderIndex] === undefined ? initialValue : state[renderIndex]
const setstate = (newValue: any) => {
state[renderIndex] = newValue
render()
}
index++
return [state[renderIndex], setstate]
}
const render = () => {
index = 0
ReactDOM.render(<Home />, document.getElementsByClassName('lego')[0]);
}