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的规则

相关推荐
甜兒.20 分钟前
鸿蒙小技巧
前端·华为·typescript·harmonyos
wang_book1 小时前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
weixin_455446172 小时前
Python学习的主要知识框架
开发语言·python·学习
Jiaberrr4 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy4 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白4 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、4 小时前
Web Worker 简单使用
前端
web_learning_3214 小时前
信息收集常用指令
前端·搜索引擎
Ylucius4 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
tabzzz4 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack