React学习计划-react-hooks补充

React Hooks

1. 使用hooks理由

  1. 高阶组件为了复用,导致代码层级复杂
  2. 生命周期的复杂

2. useState(保存组件状态)

复制代码
const [state, setstate] = useState(initialState)

3. useEffect(处理副作用)和useLayoutEffect(同步执行副作用)

  1. 使用方式:

    useEffect(() => {
    // effect
    return () => {
    // cleanup
    };
    }[依赖的状态;空数组,表示不依赖])

  2. 说明:

  • 不传入依赖:对比componentDidMount生命周期,表示初始加载完后执行
  • 传入依赖:对比componentDidMountcomponentDidUpdate生命周期,表示加载完后和更新完成后执行
  • 回调函数内return函数,对比componentWillUnmount销毁生命周期
  1. 示例:

    useEffect(()=>{
    const timer = setInterval(()=>{
    console.log('这是定时器')
    }, 1000)
    return ()=>{
    console.log('componentWillUnmount销毁时触发')
    clearInterval(timer)
    }
    },[name])

  2. useEffectuseLayoutEffect区别:

简单来说就是调用时机不同,useLayoutEffect和原来componentDidMount & componentDidUpdate一致,在react完成DOM更新后马上同步调用代码,会阻塞页面渲染。useEffect则是在整个页面渲染完才会调用代码

官方优先建议使用useEffect

在实际使用时如果想避免页面抖动 (在useEffect里修改DOM很有可能出现)的话,可以把需要操作的DOM的代码放在useLayoutEffect里,在这里做DOM操作,这些DOM修改会和react做出的更改一起被一次性渲染到屏幕上,只有一次回流、重绘的代价

4. useCallBack(记忆函数)

防止因为组件重新渲染,导致方法被重新创建,起到缓存作用,只有第二个参数变化了,才重新声明一次

复制代码
var handleClick = useCallback(()=>{
  console.log(name)
},[name])

<button onClick={()=>handleClick()}>点击</button>

// 只有name改变后,这个函数才会重新声明一次
// 如果传入空数组,那么就是第一次创建被缓存,如果name后期改变了,拿到的还是老name
// 如果传第二个参数,每次都会重新声明一次,拿到的就是最新的name

5. useMemo(记忆组件)(可以理解为Vue的计算属性)

useCallBack的功能完全可以由useMemo所取代,如果你想通过使用useMemo返回一个记忆函数也是完全可以的。

复制代码
useCallback(fn, inputs) is equivalent to useMemo(()=> fn, inputs)

唯一的区别是:useCallback不会执行第一个参数函数,而是将它返回给你,而useMemo会执行第一个函数并将函数执行结果返回给你。所以在前面的例子中,可以返回handleClick来达到存储函数的目的。

所以useCallback常用记忆事件函数,生成记忆后的事件函数并传递给子组件使用。而useMemo更适合经过函数计算得到一个确定的值,比如记忆组件。

复制代码
const getFilterList = useMemo(
  ()=> list.filter(item => item.name.toUpperCase().includes(text.toUpperCase())),
  [list, text] // 如果list和text变化
  )

6. useRef(保存引用值)

  1. 设置ref属性值

    const myRef = useRef(null)
    <Child ref={myRef}/>

  2. 用于缓存一个变量值

    const [name, setName] = useState('zhangsan')
    var mycount = useRef(0)
    <button onClick={()=>{
    setName('lisi')
    mycount.current++
    }}>点击</button>
    {name}-{mycount}

7. useReduceruseContext(减少组件层级)

  1. useContext用于组件通信,接收父组件传入的值

    // 父组件
    import React from 'react'
    var GlobalContext = React.createContext()

    function App(){
    <GlobalContext.Provider value={{
    name: '张三',
    age: 20,
    changeAge: (value) => {
    setAge(value)
    }
    }}>
    <Child />
    </GlobalContext.Provider>
    }

    // 子组件内
    function Child(){
    const text = useContext(GlobalContext)
    }

  2. useReducer:实现Reduxreducer的功能,应用在组件通信中

    const reducer = (prevState, action)=>{
    const newState = { ...prevState }
    switch(action.type){
    case 'add':
    newState.count ++
    return newState
    case 'minus':
    newState.count --
    return newState
    default:
    return prevState
    }
    }
    const initialState = {
    count: 0
    }
    // FC中
    const [state, dispatch] = useReducer(reducer, initialState)

    <button onClick={()=>{
    dispatch({
    type: 'minus'
    })
    }}>-</button>
    {state.count}
    <button onClick={()=>{
    dispatch({
    type: 'add'
    })
    }}>+</button>

8. 自定义hooks

当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。

必须以use开头吗?必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否包含其内部Hook的调用,React将无法自动检查你的Hook是否违反了Hook的规则

相关推荐
一只码代码的章鱼10 分钟前
学习笔记(算法学习+Maven)
笔记·学习·算法
冰茶_31 分钟前
WPF TextBlock控件性能优化指南
学习·性能优化·wpf·控件
JarvanMo1 小时前
借助FlutterFire CLI实现Flutter与Firebase的多环境配置
前端·flutter
keep intensify1 小时前
数据结构---单链表的增删查改
c语言·数据结构·c++·经验分享·学习·算法·分享
Jedi Hongbin1 小时前
echarts自定义图表--仪表盘
前端·javascript·echarts
凯哥19701 小时前
Sciter.js指南 - 桌面GUI开发时使用第三方模块
前端
边洛洛1 小时前
对Electron打包的exe文件进行反解析
前端·javascript·electron
财神爷亲闺女1 小时前
js 实现pc端鼠标横向拖动滚动
前端