React Hooks使用详解

useState

const [count, setCount] = useState(parameter);

1. count为保存在setState中的参数,可以为基本数据类型也可以是引用数据类型(数组,对象,函数等),未传值则为undefined;

2. setCount为改变count值时使用

3. useState保存的数据是使用链表的数据结构,如果在循环、判断或子函数内调用会使链表断开,数据会错乱。

useEffect

useEffect主要用于模拟class类组件的生命周期函数,可以在组件内多次使用,以下是三种常用方式:

1. 只执行一次,类似componentDidMount, 

useEffect(() => {

}, [])

2. 根据传入的参数发生变化则执行,类似componentDidUpdate

useEffect(() => {

}, [count])

3. 当return 一个函数表达式时,这个表达式在组件卸载后执行,类似componentWillUnmount

注:该方法意味着卸载后的操作不需要都写在componentWillUnmount, 极大方便我们去理解他人什么情况下要情空某种状态

useEffect(() => {

        return () => {}

}, [])

useCallback

useCallback使用来优化性能的,可以减少react的计算量以及不必要的渲染,但是初学者经常会在各个地方使用而导致性能更差,因此需要了解它在什么情况下适用是很有必要的。

使用方式:useCallback(Fun, [])

1. 第一个参数是函数

2. 第二个接收数组,当里面的依赖未发生变化时则不会重新触发。

例子1:

当点击ChildA,react其实会把childB也重新渲染,点击ChildB也一样。但我们想要的是点击childA时,不触发childB渲染。

function ChildA (props) {

        const {onClick, children} = props;

        return <div onClick={onClick}>{children}</div>

}

function ChildB ({onClick, name}) {

        return <div onClick={onClick}>{name}</div>

}

function Parent () {

        const [a, setA] = useState(0);

        const [b, setB] = useState(0);

        const handleClickA = () => {

                setA(a+1)

        }

        const handleClickB = () => {

                setB(b+1)

        }

        return (

                <div>

                        <ChildA onClick={handleClickA}>{a}</ChildA>

                        <ChildB onClick={handleClickB} name={b} />

                </div>

        )

}

性能优化:

function ChildA (props) {

        const {onClick, children} = props;

        return <div onClick={onClick}>{children}</div>

}

function ChildB ({onClick, name}) {

        return <div onClick={onClick}>{name}</div>

}

const ChildC = memo(ChildB); // memo可以理解成一个记忆作用,不能缺少

function Parent () {

        const [a, setA] = useState(0);

        const [b, setB] = useState(0);

        const handleClickA = () => {

                setA(a+1)

        }        

        const handleClickB = useCallback(() => {setB(b+1)}, [b])// 点击A时,由于b未改变所以只会更新ChildA,不会重新渲染ChildB。

        return (

                <div>

                        <ChildA onClick={handleClickA}>{a}</ChildA>

                        <ChildC onClick={handleClickB} name={b} />

                </div>

        )

}

注意:因为ChildA未做优化,所以点击ChildB时ChildA也会渲染,只要将ChildA同样处理即可。

useContext

useContext可以使组件间互相传值,使用方式参考useReducer的例子3;

useRef

function Input () {

        const inputRef = useRef();

        useEffect(() => {

                console.log(inputRef.current); // 输出input节点   inputRef.current.value可以获取输入框的值

        }, [])

        return (

                <div>

                        <input ref={inputRef} />                    

                </div>

        )

}

useReducer

useReducer是useState的一种替代方法。使用的原因如下:

1. 当页面需要使用到很多数据或者数据有关联时,使用useState会造成代码臃肿。合理使用useReducer不仅可以减少重复的代码,还能提高页面的性能。

2. 使用useState时,例如page, pageSize, total都是存放在state里面,但是state并不会帮我们合并这些数据,但是useReducer可以帮我们将这个内容合并到我们想要创造的一个对象内,例如最终可以返回{page: 1, pageSize: 10, total: 0}

何时使用:

基本数据类型使用useState, 引用数据类型(数组或对象)使用useReducer。

使用方法:

const [state, dispatch] = useReducer(reducer, initialValue, init);

reducer: 是一个函数,使用dispatch去更新state的值时,使用的函数是reducer;

initialValue: 初始值

init:是一个函数,返回的值会更新state,一般不传。

例子1:

function reducer(state, action) {

        switch (action) {

                case 'add':

                        return state + 1;

                case 'sub':

                        return state - 1;

                default: 

                        return state

        }

}

function CountComponent () {

        const [count, dispatch] = useReducer(reducer, 0);

        // const [count, dispatch] = useReducer(reducer, 0,()=> 1); 此时的count为1

        return (

                <div>

                        <div>{count}</div>

                        {/*点击加count则加1, 点击减count则减一*/}

                        <button onClick={() => {dispatch('add')}}>加</button>

                        <button onClick={() => {dispatch('sub')}}>减</button>

                </div>

        )

}

例子2:

function reducer(state, action) {

        switch (action.type) {

                case 'add':

                        return state + action.param;

                case 'sub':

                        return state - action.param;

                default: 

                        return state

        }

}

function CountComponent () {

        const [count, dispatch] = useReducer(reducer, 0);

        return (

                <div>

                        <div>{count}</div>

                        {/*点击加count则加1, 点击减count则减一*/}

                        <button onClick={() => {dispatch({ type: 'add', param: 1 })}}>加</button>

                        <button onClick={() => {dispatch({ type: 'sub', param: 1 })}}>减</button>

                </div>

        )

}

例子3(与useContext搭配使用):

创建CountContext.js

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

const CountContext = React.createContext();

export default CountContext;

// 开始使用

function reducer(state, action) {

        switch (action.type) {

                case 'add':

                        return state + action.param;

                case 'sub':

                        return state - action.param;

                default: 

                        return state

        }

}

function Child () {

        const countContext = useContext(CountContext);

        return (

                <CountContext.Provider value={{count, dispatch}}>

                        <Child />

                        <div>{countContext.count}</div>

                        {/*点击加count则加1, 点击减count则减一*/}

                        <button onClick={() => {countContext.dispatch({ type: 'add', param: 1 })}}>加</button>

                        <button onClick={() => {countContext.dispatch({ type: 'sub', param: 1 })}}>减</button>

                </CountContext.Provider>

        )

}

function CountComponent () {

        const [count, dispatch] = useReducer(reducer, 0);

        return (

                <CountContext.Provider value={{count, dispatch}}>

                        <Child />

                </CountContext.Provider>

        )

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值