Web开发编程网
分享Web开发相关技术

React Hooks 理解

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)
复制代码

代码 优先使用这种

  1. useReducer

分为四步

  • 创建初始值initialState
  • 创建所有操作reducer(state,action)
  • 传给sueReducer,得到读和写API
  • 调用写({type:’操作类型 ‘})
  • 总的来说useState是useState的复杂版
  • 示例代码

一个用useReducer的表单例子

链接

3. 如何代替Redux

步骤

  1. 将数据集中在一个store对象

例子

4. UseContext

上下文

  • 全局变量是全局的上下文
  • 上下文是局部的全局变量

使用方法

  1. 使用C=createContext(initial)创建上下文

注意事项

  • 不是响应式的,在一个模块将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

作者:lnn520
链接:https://juejin.cn/post/6928574472655994893
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

未经允许不得转载:WEB开发编程网 » React Hooks 理解

WEB开发编程网

谢谢支持,我们一直在努力

安全提示:您正在对WEB开发编程网进行赞赏操作,一但支付,不可返还。