React + hook

211 阅读3分钟

React + hook

hook简介

hook是React 16.8的新增特性。它可以让你在不编写 class 的情况下使用 state以及其他的React特性。

为什么要用hook

它可以让函数组件也拥有类组件的特性。

它能为你解决那些问题

解决函数组件的一些不足:

1、无法定义状态。

利用useState。可以为函数组件声明状态

2、没有生命周期。

利用useEffect。可以模仿类组件的声明周期:

componentDidMount,

componentDidUpdata,

componentWillUnmount

下面是hook的一些API

常用API及使用方法

useState

让无状态组件拥有状态

//从react中解构useState 
import {useState} from 'react'; 
function App() { 
    //声明一个数组 数组中的值为:[ ‘变量名’,'修改变量的函数' ] 
    //修改变量的函数 必须以set开头,并且用驼峰命名   
    const [cont,setCont]=useState(1)   
    return (     
        <div className="App">      
            <header className="App-header">         
            {cont} 
            //通过事件触发 setCont(‘any’)        
            <button 
            onClick={()=>{setCont(cont+1)}}
            >
            +++
            </button>      
            </header>    
        </div>  
    );
}
export default App;

useEffect

副作用函数

//从react中解构 useEffect 
import { useEffect } from 'react'; 
function App() { 
    /* effect使用方法 
    useEffect('回调函数','依赖列表:可以不传') 
    effect的四种状态 
    1、 不传依赖表 
        useEffect(()=>{     console.log('张涛');   }) 
    2、 传入空依赖表。类似于componentDidMount 
        useEffect(()=>{     console.log('张涛');   },[]) 
    3、 传入依赖表,并且依赖一个变量,类似于componentDidUpData 
        useEffect(()=>{     console.log('张涛');   },[cont]) 
    3、 返回一个函数类似于 componentWillUnmount 
        useEffect(()=>{     console.log('张涛'); return()=> {};   },[]) 
    */   
    useEffect(()=>{     console.log('张涛');   })  
    return (    
        <div className="App"> 
        <header className="App-header">
        {cont}    
        <button onClick={()=>{setCont(cont+1)}}>            +++          </button>     
        </header>     
        </div>
    );
}
export default App;

useContext

跨组件传值

//从react中解构 useContext 
import { useContext } from 'react'; 
//用于跨组件传值,类似于createContext 
const themes = {  
    light: {
        foreground: "#000000",
        background: "#eeeeee"  
    },
    dark: {
        foreground: "#ffffff",
        background: "#222222" 
    } 
}; 
//声明跨组件传值   const ThemeContext = React.createContext(themes.light);  
function App() {     
    return ( 
        //ThemeContext.Provider 作为提供方 传入一个value       
        <ThemeContext.Provider value={themes.dark}> 
            <Toolbar />      
        </ThemeContext.Provider>
    );
}  

function Toolbar(props) {
    return (
        <div>
            <ThemedButton />
        </div>
    );
}
function ThemedButton() {
    //接受提供方传过来的 value     
    const theme = useContext(ThemeContext);
    return (  
        <button style={{ background: theme.background, color: theme.foreground }}>  
        I am styled by theme context! 
        </button>
    );
}

额外的 hook API 及使用方法

useReducer

小型redux

//从react中解构 useReducer 
import { useReducer } from 'react'; 
//定义仓库状态 
const initialState = {count: 0}; 
//定义修改状态的函数 
function reducer(state, action) { 
    switch (action.type) {
        case 'increment':
            return {count: state.count + 1};
        case 'decrement':
            return {count: state.count - 1};
        default: throw new Error();
    }
}
function Counter() {
/* 使用方法 声明一个数组 = useReducer( '改变状态的函数','仓库状态/初始化数据' )
    const [ state,dispatch ]=userReducer(reducer,initialState)
    */
    const [state, dispatch] = useReducer(reducer, initialState);
    return ( 
        <> 
            Count: {state.count} 
            <button onClick={() => dispatch({type: 'decrement'})}>-</button> 
            <button onClick={() => dispatch({type: 'increment'})}>+</button> 
        </>
    );
}

useCallback

给予依赖后类似于shouldComponentUpdate

//从react中解构 useCallback 
import { useCallback } from 'react';
//useCallback 有返回值 返回一个函数 
// 在依赖数据修改时才会触发事件。官方介绍类似于shouldComponentUpdate 
const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], );

useMemo

类似于Vue中的计算属性

//从react中解构 useMemo 
import { useMemo } from 'react'; 
// useMemo有返回值 返回一个新的值 
//使用方法 声明一个变量 = useMemo('毁掉函数',依赖列表 || null) 
//类似于Vue中的计算属性 判断依赖是否更新,更新执行函数 不更新不做改变
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useRef

获取dom

//从react中解构 useRef 
import { useRef } from 'react'; 
function TextInputWithFocusButton() { 
    const inputEl = useRef(null);
    const onButtonClick = () => { 
        // `current` 指向已挂载到 DOM 上的文本输入元素
        inputEl.current.focus(); };
        return (
            <>
                <input ref={inputEl} type="text" />
                <button onClick={onButtonClick}>Focus the input</button>
            </> 
    );
}

hook优缺点

hook的优点:

u=3836828368,2050848475&fm=253&fmt=auto&app=138&f=JPEG.webp

我认为是让我们可以更好的利用函数组件去做一些事情。相比于类组件减少了很多代码,让整个组件看起来不是很乱。同时也不需要考虑this指向的问题。

u=1873154320,3496170329&fm=26&fmt=auto.webp

有优点一定就会有缺点嘛,下面就是hook的缺点

hook的缺点: 我认为hook的缺点就是声明周期不够完善,不如class组件那么灵活还有比如 useRef在使用哦时也不如直接使用ref(自我感觉)。

总结

比起用函数组件 + hook 我更习惯于用class,尽管代码量和代码的阅读体验不是很好,但是类组件是真的香。