ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Hook钩子函数--useReducer

2021-11-22 15:36:24  阅读:165  来源: 互联网

标签:count return 修改 -- useReducer dispatch Hook state


1.介绍

(1)作用:“勾住”某些自定义数据对应的dispatch所引发的数据更改事件。useReducer可以替代useState,实现更为复杂逻辑的数据修改。  

(2)解决什么问题:useReducer是useState的升级版(实际上应该是原始版),可以实现复杂逻辑修改,而不是像useState那样只是直接赋值修改。

2.useReducer基础用法

useReducer(reducer,initialValue)函数通常传入2个参数,第1个参数为我们定义的一个“由dispatch引发的数据修改处理函数”,第2个参数为自定义数据的默认值,useReducer函数会返回自定义变量的引用和该自定义变量对应的“dispatch”。       import React, { useReducer } from 'react'; //引入useReducer         //定义好“事件处理函数” reducer     function reducer(state, action) {       switch (action) {         case 'xx':             return xxxx;         case 'xx':             return xxxx;         default:             return xxxx;       }     }
    function Component(){       //声明一个变量xxx,以及对应修改xxx的dispatch       //将事件处理函数reducer和默认值initialValue作为参数传递给useReducer       const [xxx, dispatch] = useReducer(reducer, initialValue);
      //若想获取xxx的值,直接使用xxx即可             //若想修改xxx的值,通过dispatch来修改       dispatch('xx');     } 3.基础案例: 若某React组件内部有一个变量count,默认值为0,有3个button,点击之后分别可以修改count的值。3个按钮具体的功能为:第1个button点击之后count+1,第2个button点击之后count -1,第3个button点击之后 count x 2 (翻倍)。  
    import React, { useReducer } from 'react';
    function reducer(state,action){       switch(action){         case 'add':             return state + 1;         case 'sub':             return state - 1;         case 'mul':             return state * 2;         default:             console.log('what?');             return state;       }     }
    function CountComponent() {       const [count, dispatch] = useReducer(reducer,0);
      return <div>         {count}         <button onClick={() => {dispatch('add')}} >add</button>         <button onClick={() => {dispatch('sub')}} >sub</button>         <button onClick={() => {dispatch('mul')}} >mul</button>       </div>;     }
    export default CountComponent;   如果希望按钮点击之后,能够自主的控制增加多少,减少多少,或者乘以多少     import React, { useReducer } from 'react';
    function reducer(state,action){       //根据action.type来判断该执行哪种修改       switch(action.type){         case 'add':           //count 最终加多少,取决于 action.param 的值           return state + action.param;         case 'sub':           return state - action.param;         case 'mul':           return state * action.param;         default:           console.log('what?');           return state;       }     }
    function getRandom(){       return Math.floor(Math.random()*10);     }
    function CountComponent() {       const [count, dispatch] = useReducer(reducer,0);
      return <div>         {count}         <button onClick={() => {dispatch({type:'add',param:getRandom()})}} >add</button>         <button onClick={() => {dispatch({type:'sub',param:getRandom()})}} >sub</button>         <button onClick={() => {dispatch({type:'mul',param:getRandom()})}} >mul</button>       </div>;     }
    export default CountComponent;    4.useReducer高级用法 (1)使用useReducer来管理复杂类型的数据     举例,若某组件内通过ajax请求数据,获取最新一条站内短信文字,需要组件显示整个ajax过程及结果:   ①当ajax开始请求时,界面显示“loading...”;   ②当ajax请求发生错误时,界面显示“wrong!”;   ③当ajax请求成功获取数据时,界面显示获取到的数据内容; 伪代码:     const initralData = {loading: true,result: '',error: false};     const reducer = (state, action) => {       switch (action.type) {         case 'succes':             return {loading:false,result:action.res,error:false}         case 'error':             return {loading:false,error:true}       }     }         function Component() {       const [state, dispatch] = useReducer(reducer, initralData);           {           //ajax请求成功情况下           dispatch({type:'succes',res:'You have a good news!'});               //ajax请求错误情况下           dispatch({type:'error'});       }           return <div>         {state.loading ? 'loading...' : state.result}         {state.error ? 'wrong!' : null}       </div>     }   (2)使用useContext和useReducer实现全局共享数据 实现的原理:用useContext实现“获取全局数据”;用userReducer实现“修改全局数据” 实现的思路:① 用React.createContext()定义一个全局数据对象                       ②在父组件中用userReducer定义全局变量xx和负责抛出事件的dispatch                       ③在父组件之外,定义负责具体修改全局变量的处理函数reducer,根据修改xx事件类型和参数,执行修改xx的值                       ④在父组件中用<XxxContext.Provider value={{xx,dispathc}}>标签把全局共享数据和负责抛出修改xx的dispatch暴露给子组件                       ⑤在子组件中用useContext获取全局变量                       ⑥在子组件中用xxContext.dispatch去抛出修改xx的事件,携带修改事件类型和参数 假如有全局变量数据count,有不同的子组件均可以获取并且修改全局变量count CountContext.js: ①共享对象:     import React from 'react';     const CountContext = React.createContext();     export default CountContext; 父组件: import React, { useReducer } from 'react'; import CountContext from './CountContext'; import ComponentA from './ComponentA'; import ComponentB from './ComponentB'; import ComponentC from './ComponentC';
const initialCount = 0; //定义count的默认值   // 修改count事件处理函数,根据u修改参数进行处理 //③在父组件之外,定义负责具体修改全局变量的处理函数reducer,根据修改xx事件类型和参数,执行修改xx的值; function reducer(state, action) {     switch (action.type) {         case 'add':             return state + action.param;         case 'sub':             return state - action.param;         case 'mul':             return state * action.param;         case 'reset':             return initialCount;         default:             console.log("what?");             return state;     } } export default function father() { // ②在父组件中用 userReducer 定义全局变量count和负责抛出修事件的dispatch;     const [count, dispatch] = useReducer(reducer, initialCount);     // value={{ count, dispatch }是整个代码的核心,把将count、dispatch暴露给所有的子组件     // ④在父组件中用 <XxxContext.Provider value={{xx,dispathc}}> 标签把 全局共享数据和负责抛出修改xx的dispatch 暴露给子组件;       return <CountContext.Provider value={{ count, dispatch }}>         <div>             ParentComponent - count = {count}             <ComponentA />             <ComponentB />             <ComponentC/>         </div>         </CountContext.Provider> } 子组件: import React,{ useState, useContext } from 'react'; import CountContext from './CountContext'; export default function ComponentA() {     const [param, setParam] = useState(1);     // 引入全局共享对象,获取全局变量count,以及修改count对应的dispatch     //⑤在子组件中用 useContext 获取全局变量;     const countContext = useContext(CountContext)     const inputChangeHandler = (eve) => {         setParam(eve.target.value)     }     const doHandler = () => {         //若想修改全局count,先获取count对应的修改抛出事件对象dispatch,然后通过dispatch将修改内容抛出         //抛出的修改内容为:{type:'add',param:xxx},即告诉count的修改事件处理函数,本次修改的类型为add,参数是param         //这里的add和param完全是根据自己实际需求自己定义的         // ⑥在子组件中用 xxContext.dispatch 去抛出修改xx的事件,携带修改事件类型和参数;         countContext.dispatch({type:'add',param:Number(param)});       }         const resetHandler = () => {         //⑥在子组件中用 xxContext.dispatch 去抛出修改xx的事件,携带修改事件类型和参数;         countContext.dispatch({type:'reset'});     }     return <div>     ComponentA - count={countContext.count}     <input type='number' value={param} onChange={inputChangeHandler} />     <button onClick={doHandler}>add {param}</button>     <button onClick={resetHandler}>reset</button> </div>     }

 

 




标签:count,return,修改,--,useReducer,dispatch,Hook,state
来源: https://www.cnblogs.com/z8g1z7/p/15588757.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有