React Hooks常用场景的利用(小结)(2)

// bad,不推荐 function Example({ someProp }) { function doSomething() { console.log(someProp); } useEffect(() => { doSomething(); }, []); // 🔴 这样不安详(它挪用的 `doSomething` 函数利用了 `someProp`) } // good,推荐 function Example({ someProp }) { useEffect(() => { function doSomething() { console.log(someProp); } doSomething(); }, [someProp]); // ✅ 安详(我们的 effect 仅用到了 `someProp`) }

假如处于某些原因你无法把一个函数移动到 effect 内部,尚有一些其他步伐:

你可以实验把谁人函数移动到你的组件之外。那样一来,这个函数就必定不会依赖任何 props 或 state,而且也不消呈此刻依赖列表中了;

万不得已的环境下,你可以 把函数插手 effect 的依赖但 把它的界说包裹 进 useCallback Hook。这就确保了它不随渲染而改变,除非它自身的依赖产生了改变;

推荐启用 中的 exhaustive-deps 法则,此法则会在添加错误依赖时发出告诫并给出修复发起 ;

// 1、安装插件 npm i eslint-plugin-react-hooks --save-dev // 2、eslint 设置 { "plugins": [ // ... "react-hooks" ], "rules": { // ... "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" } }

7、一些重点

(1)可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate和 componentWillUnmount这三个函数的组合;
(2)在 React 的 class 组件中,render 函数是不该该有任何副浸染的; 一般来说,在这里执行操纵太早了,我们根基上都但愿在 React 更新 DOM 之后才执行我们的操纵。

三、useContext

用来处理惩罚多层级通报数据的方法,在以前组件树中,跨层级祖先组件想要给孙子组件通报数据的时候,除了一层层 props 往下透传之外,我们还可以利用 React Context API 来帮我们做这件事。利用例子如下所示
(1)利用 React Context API,在组件外部成立一个 Context

import React from 'react'; const ThemeContext = React.createContext(0); export default ThemeContext;

(2)利用 Context.Provider提供了一个 Context 工具,这个工具可以被子组件共享

import React, { useState } from 'react'; import ThemeContext from './ThemeContext'; import ContextComponent1 from './ContextComponent1'; function ContextPage () { const [count, setCount] = useState(1); return ( <div className="App"> <ThemeContext.Provider value={count}> <ContextComponent1 /> </ThemeContext.Provider> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); } export default ContextPage;

(3)useContext()钩子函数用来引入 Context 工具,而且获取到它的值

// 子组件,在子组件中利用孙组件 import React from 'react'; import ContextComponent2 from './ContextComponent2'; function ContextComponent () { return ( <ContextComponent2 /> ); } export default ContextComponent; // 孙组件,在孙组件中利用 Context 工具值 import React, { useContext } from 'react'; import ThemeContext from './ThemeContext'; function ContextComponent () { const value = useContext(ThemeContext); return ( <div>useContext:{value}</div> ); } export default ContextComponent;

四、useReducer
1、基本用法

比 useState 更合用的场景:譬喻 state 逻辑处理惩罚较巨大且包括多个子值,可能下一个 state 依赖于之前的 state 等;例子如下所示

import React, { useReducer } from 'react'; interface stateType { count: number } interface actionType { type: string } const initialState = { count: 0 }; const reducer = (state:stateType, action:actionType) => { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; default: throw new Error(); } }; const UseReducer = () => { const [state, dispatch] = useReducer(reducer, initialState); return ( <div className="App"> <div>useReducer Count:{state.count}</div> <button onClick={() => { dispatch({ type: 'decrement' }); }}>useReducer 淘汰</button> <button onClick={() => { dispatch({ type: 'increment' }); }}>useReducer 增加</button> </div> ); }; export default UseReducer;

2、惰性初始化 state

interface stateType { count: number } interface actionType { type: string, paylod?: number } const initCount =0 const init = (initCount:number)=>{ return {count:initCount} } const reducer = (state:stateType, action:actionType)=>{ switch(action.type){ case 'increment': return {count: state.count + 1} case 'decrement': return {count: state.count - 1} case 'reset': return init(action.paylod || 0) default: throw new Error(); } } const UseReducer = () => { const [state, dispatch] = useReducer(reducer,initCount,init) return ( <div className="App"> <div>useReducer Count:{state.count}</div> <button onClick={()=>{dispatch({type:'decrement'})}}>useReducer 淘汰</button> <button onClick={()=>{dispatch({type:'increment'})}}>useReducer 增加</button> <button onClick={()=>{dispatch({type:'reset',paylod:10 })}}>useReducer 增加</button> </div> ); } export default UseReducer;

五、Memo

如下所示,当父组件从头渲染时,子组件也会从头渲染,纵然子组件的 props 和 state 都没有改变
import React, { memo, useState } from 'react';

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsjfjx.html