react hooks
useState
const [n, setN] = React.useState(0)
const [user, setUser] = React.useState({name: 'Jack', age: 18})
=======
不可局部更新
const [user, setUser] = React.useState({name: 'Jack', age: 18})
const onClick = () =>{
//setUser不可以局部更新,如果只改变其中一个,那么整个数据都会被覆盖
// setUser({
// name: 'Frank'
// })
setUser({
...user, //拷贝之前的所有属性
name: 'Frank' //这里的name覆盖之前的name
})
=========
地址要变
setState(obj) 如果obj地址不变,那么React就认为数据没有变化,不会更新视图
===========
useState
const [state, setState] = useState(() => {return initialState})
该函数返回初始state,且只执行一次
==========
setN(i => i + 1)
=========
useReducer
用来践行Flux/Redux思想
一、创建初始值initialState
二、创建所有操作reducer(state, action);
三、传给userReducer,得到读和写API
四、调用写({type: '操作类型'})
==========
如何代替 Redux
一、将数据集中在一个 store 对象
二、将所有操作集中在 reducer
三、创建一个 Context
四、创建对数据的读取 API
五、将第四步的内容放到第三步的 Context
六、用 Context.Provider 将 Context 提供给所有组件
七、各个组件用 useContext 获取读写API
==========
useContext
全局变量是全局的上下文
上下文是局部的全局变量
=========
一、使用 C = createContext(initial) 创建上下文
二、使用 <C.Provider> 圈定作用域
三、在作用域内使用 useContext(C)来使用上下文
==========
useEffect
对环境的改变即为副作用,如修改 document.title
但我们不一定非要把副作用放在 useEffect 里面
实际上叫做 afterRender 更好,每次render后执行
=========
一、作为 componentDidMount 使用,[ ] 作第二个参数
二、作为 componentDidUpdate 使用,可指定依赖
三、作为 componentWillUnmount 使用,通过 return
===========
useLayoutEffect
useEffect 在浏览器渲染完成后执行
useLayoutEffect 在浏览器渲染前执行
为了用户体验,优先使用 useEffect (优先渲染)
============
useMemo
将代码中的 Child 用React.memo(Child) 代替
如果 props 不变,就没有必要再次执行一个函数组件
======
useMemo
第一个参数是 () => value
第二个参数是依赖 [m, n]
只有当依赖变化时,才会计算出新的 value
=============
useCallback
useCallback(x => console.log(x), [m]) 等价于
useMemo( () => x => console.log(x), [m])
===============
forwardRef
useRef
可以用来引用 DOM 对象
也可以用来引用普通对象
==========
forwardRef
props 无法传递 ref 属性
实现 ref 的传递:由于 props 不包含 ref,
所以需要 forwardRef
===========
自定义 Hook