一个前端,爱跑步、爱吉他、爱做饭、爱生活、爱编程、爱南芳姑娘,爱我所爱。世间最温暖又无价的是阳光、空气与爱,愿它们能带你去更远的地方。

  • 文章
  • 心情
  • 照片墙
  • 工具
  • 开发技术分享

    ReactHooks学习记录

    技术 315 2019-11-28 16:53

    1.useState

    引入useState

    import React, { useState } from 'react';
    

    在无状态组件中去声明一个useState

    function test() {
    // 解构赋值 useState传递的参数为初始值 跟前面的[num,setUnm] 没有关系。。
    const [num,setNum] = useState(0)
    //在页面渲染这个值
    return(
           <div>
             你点击了 {num}次 <br/><br/>
    //每点击一次 即可增加
              <button onClick={()=>{setNum(num+1)}}>点我</button>
             </div>
    )
    }
    

    使用这样的方式写组件很方便..

    2.useEffect

    引入useEffect:

    import React, { useEffect,useState } from 'react';
    

    在组件中使用:

    function tesst(){
    const [num,setNum] = useState(0)
        // useEffect相当于是一个生命周期 异步
        // 组件渲染完成后和组件更新时 调用
        // componentDidMount 和 componentDidUpdate
        useEffect(()=>{
            console.log(num)
    //return意思为解绑 当组件销毁时调用
      return()=>{
                console.log('老弟走了!')
            }
    // 空数组[]时,就是当组件将被销毁时才进行解绑
    // 实现了componentWillUnmount的生命周期函数
        },[])
    }
    

    3.useContext和createContext

    // 1引用userContext和createContext来传参

    import React, { useState,useContext,createContext } from 'react';
    

    //2创建一个createContext上下文

    const NumContent = createContext();
    

    // 4.创建子路由

    function Didi(){
        // 4.1使用useContext来接收父组件传递的参数
        let Num = useContext(NumContent)
        return(
            <h1>我是弟弟{Num}</h1>
        )
    }
    function Exp2(){
        const [Num,setNum] = useState(0)
        return(
            <div>
                <h1>{Num}</h1>
                <button onClick={()=>{setNum(Num+1)}}>点击增加</button>
                {/* 3.在组件中是引入NumContent.Provider 固定写法  value是要传递的参数 */}
                <NumContent.Provider value={Num}>
                    {/* 5在组件NumContent.Provider内部写入 子组件 */}
                    <Didi/>
                </NumContent.Provider>
            </div>
            
        )
    }
    export default Exp2;
    

    4.useReducer

       import React, { useReducer } from 'react';
        // 创建一个reducer 传递两个参数 一个是传递的值 一个是如何控制这个值
        function ReducerDemo(){
            // useReducer需要传递两个参数 1一个是reducer本身,一个是初始值
            // 前面的两个变量count是初始值,dispatch是派发器用来控制初始值
            // useReducer本身中的state对应的是初始值,action对应的是dispatch传递的参数
            const [count,dispatch]  = useReducer((state,action)=>{
                    switch(action){
                        case 'add':{
                            return state+1
                        }
                        case 'sub':{
                            return state-1
                        }
                        default:{
                            return state
                        }
                    }
                },0)
                return(
                    <div>
                        <h2>现在的分数是{count}</h2>
                        <button onClick={()=>dispatch('add')}>Increment</button>
                        <button onClick={()=>dispatch('sub')}>Decrement</button>
                    </div>
                )
        }
    
    export default ReducerDemo
    

    5.useMemo

    useMemo主要用来解决使用React hooks产生的无用渲染的性能问题

    问题描述:点击志玲按钮的时候 子组件的小白changeXiaobai()也会执行 又重复的渲染了一次

    期望:点击相对应的按钮 只渲染相对应的组件 无相关的组件不重复的去渲染

    解决方案:使用useMemo来规避重复渲染的问题

    import React,{useState,useMemo} from 'react';
    function Exp5(){
        const [xiaobai,setXiaobai] = useState('小白正在等待')
        const [zhiling,setZhiling] = useState('志玲正在等待')
        return (
            <div>
                <hr/>
                <button onClick={()=>{
                    setXiaobai(new Date().toLocaleTimeString())
                }}>
                    小白
                </button>
                <button onClick={()=>{
                    setZhiling(new Date().toLocaleTimeString()+'志玲来了')
                }}>
                    志玲
                </button> <br/> <br/>
                {/* 向子组件传递两个值 */}
                {/* 如果传递在组件中 而不是以属性的方式传递,在子组件中使用children接收 */}
                <Child name={xiaobai} name2={zhiling}></Child>
            </div>
        )
    }
    //子组件
    function Child({name,name2,children}){
        function changeXiaobai(name){
            console.log('小白来了')
            return name +'你喊了一声小白 小白走过来了'
        }
        //使用useMemo 两个参数第一个是渲染的组件的方法 ,第二个是对应参数变化(条件) 下面的例子解释为只有name变化时候才 执行actionXiaobai() 这个函数
        const actionXiaobai = useMemo(()=>changeXiaobai(name),[name])
        return(
            <div>
                <div>{actionXiaobai}</div>
                <div>{name2}</div>
            </div>
        )
    }
    export default Exp5
    

    6.useRef:

    两个用处:用useRef获取React JSX中的DOM元素、用useRef来保存变量

    import React,{useRef,useState,useEffect} from 'react';
    // useRef获取React JSX中的DOM元素
    // useRef来保存变量
    function Exp6(){
        // 声明一个dom变量 默认为Null 下面进行绑定
        const inputEl = useRef(null)
        // 声明一个方法
        const onButtonClick = ()=>{
            inputEl.current.value = '你好彪哥'
            // console.log(inputEl.current.value )
        }
        //保存变量
        const textRef = useRef()
        const [text,setText] = useState('彪哥')
        useEffect(()=>{
            textRef.current = text
            console.log('textRef.current',textRef.current)
        })
        return (
            <div>
                {/* 跟上面声明的inputEl进行绑定 */}
                <input ref={inputEl} type="text"></input>
                <button onClick={onButtonClick}>展示文字</button>
                <hr/>
                <input value={text} onChange={(e)=>{setText(e.target.value)}}></input>
            </div>
        )
    }
    export default Exp6
    

    7.自定义hooks函数

    一个自定义Hooks函数,要用use开头,区分出什么是组件,什么是自定义函数。
    下面自定义Hooks函数获取窗口大小
    import React,{useEffect,useState} from 'react';
    function useSizeChange(){
        //获取当前浏览器的宽高
        let [size,setSize] = useState({
            width:document.documentElement.clientWidth,
            height:document.documentElement.clientHeight
        })
        //声明一个改变浏览器宽高的方法
        let setSizeAction = () =>{
            setSize({
                width:document.documentElement.clientWidth,
                height:document.documentElement.clientHeight
            })
        }
        //在useEffect周期函数中调用
        useEffect(()=>{
            window.addEventListener('resize',setSizeAction)
            //离开页面时解绑resize事件
            return()=>{
                window.removeEventListener('resize',setSizeAction)
            }
        },[])
        // 把size返回出去 在下面Exp7函数中使用(相当于是一个闭包)
        return size
    }
    function Exp7(){
        var size = useSizeChange()
        return (
            <div>
                窗口的Sizi:{size.width}*{size.height}
            </div>
        )
    }
    export default Exp7
    

    上一篇:Next.js学习

    下一篇:React路由学习