1. useState
使用状态
const [n,setN] = React.useState(0)
const [user,setUser] = React.useState({name:'M'})
注意事项
- 如果state是一个对象,能否部分setState?
- 答案是不可以,示例代码
- 因为setState不会帮我们合并属性,而且useReducer也不会帮我们合并
注意事项2:地址要变
- setState(obj)如果obj地址不变,那么React就认为数据没有变化
useState接受函数
const [state,setState] = useState(()=>{
return initialState
})
- 该函数返回初始state,且只执行一次
setState接受函数
setN(i=>i+1)
代码 优先使用这种
2. useReducer
分为四步
- 创建初始值initialState
- 创建所有操作reducer(state,action)
- 传给sueReducer,得到读和写API
- 调用写({type:'操作类型 '})
- 总的来说useState是useState的复杂版
- 示例代码
一个用useReducer的表单例子
链接
3. 如何代替Redux
步骤
-
- 将数据集中在一个store对象
-
- 将所有的操作集中在reducer
-
- 创建创建Context
-
- 创建对数据的读写API
-
- 将第四部的内容放到第三部的Context
-
- 用Context.Provider将Context提供给所有组件
-
- 各个组件用useContext获取读写API
例子
- 代码
- 模块化
4. UseContext
上下文
- 全局变量是全局的上下文
- 上下文是局部的全局变量
使用方法
-
- 使用C=createContext(initial)创建上下文
-
- 使用<C.provider>圈定作用域
-
- 在作用域内使用useContext(C)来使用上下文
-
- 代码示例
注意事项
- 不是响应式的,在一个模块将C的值改变,另一个模块不会感知这个变化
5. useEffect
副作用
- 对环境改变即为副总用,如修改document.title
- 但我们不一定非要把副作用放在useEffect里
- 实际上叫做afterRender更好,每次render后运行
用途
- 作为componentDidMount使用,[]作第二个参数
- 作为componentDidUpdate使用,可指定依赖
- 作为componentWillUnmount使用,通过return
- 以上三种可同时存在
特点
- 如果同时存在多个useEffect,会按照出现次序执行
6. uselayoutEffect
布局的副作用
- useEffect在浏览器渲染完成后执行
const BlinkyRender = () => {
const [value, setValue] = useState(0);
useEffect(() => {
document.querySelector('#x').innerText = `value: 1000`
}, [value] );
return (
<div id="x" onClick={() => setValue(0)}>value: {value}</div>
);
};
ReactDOM.render(
<BlinkyRender />,
document.querySelector("#root")
);
- useLayoutEffect在浏览器渲染前执行
- 例子
特点
- useLayoutEffect总是比useEffect先执行
- useLayoutEffect里的任务最好影响了Layout
经验
- 为了用户的体验,优先使用useEffect(优先渲染)
7. useMemo
React.memo
- React默认有多余的render
- 代码中Child用React.memo(Child)代替
- 如果props不变,就没有必要再次执行一个函数组件
- 最终效果示例
但是
- 这个有一个bug:代码
- 添加数据监听后,就会失效
- 因为App运行时会在次执行第12行,生成新的函数
- 新旧函数虽然功能一样,但是地址不一样
- 这时就要使用useMemo:代码
特点
- 第一个参数是()=>value,见定义
- 第二个参数是依赖[m,n]
- 只有当依赖变化时,才会计算出新的value
- 如果以来不变,那么就重用之前的value
- 相当于vue2中的computed
注意
- 如果你的value是个函数,那么你就要写成useMemo(()=>(x)=>console.log(x))
- 这是一个返回函数的函数
8. useCallback
用法
- useCallback(x=>log(x),[m])等价于
- useMemo(()=>x=>log(x),[m])
9. useRef
目的
- 如果你需要一个值,在组件不断render时保持不变
- 初始化:const count = useRef(0)
- 读取:count.current
- 需要current是为了保证两次useRef是同一个值
延伸
- 看看Vue3的ref
- 初始化:const count = ref(0)
- 读取:count.value
- 不同点:当count.value变化时,Vue3会自动render
10. forwardRef
示例
- demo1:props无法传递ref属性
- demo2:实现ref的传递
- demo3:两次ref的传递得到button的引用
useRef
- 可以用来引用DOM对象
- 也可以用来引用普通对象
forwardRef
- 由于props不包含ref,所以需要forwarfRef
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!