Hooks demo点击按钮改变文字颜色 (react学习之useContext、useReducer)

Hooks demo

1️⃣
最近在做vue无缝衔接react项目的准备,就找了个react中灰常重要❕🉐️Hooks的小练习来训练一下

前情提要:你需要优先学习html、css、js(👀特别是ES新特性)或者学习过Vue.js😉

不然学起react来,还是会比较吃力😩,因为我即使是上面几样都学过,也会觉得react有点难度(毕竟是普遍认为最难的框架)

✌️开始吧

今天的案例来自B站技术胖老师的教程,感兴趣的朋友直接去看视频,以下内容搭配了自己的理解

技术胖老师的教程

react官网

点击按钮改变文字颜色 在这里插入图片描述
在这里插入图片描述

构建4个组件[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BWV0MuBs-1660268745305)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/00d3cf70615b421d94bdaee486502b3f~tplv-k3u1fbpfcp-zoom-1.image)]

  • Buttons存放按钮
  • Color存放共享state和最外层的组件
  • hooks-demo为总组件,组合各个子组件
  • showArea展示文字组件

1.color.js

此文件负责处理共享state状态和处理state的一些逻辑(简单的逻辑用useState会更合适,但这里我们为了熟悉Hooks 使用useReducer)

1.1 useContext()

官网定义如下:

接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。

当组件上层最近的 <MyContext.Provider> 更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext provider 的 context value 值。即使祖先使用 React.memoshouldComponentUpdate,也会在组件本身使用 useContext 时重新渲染

所以我们需要先创建一个Context

export const ColorContext  = createContext()
// 如果其他组件需要使用(在Buttons中会用到),就需要export 暴露出去 因为不是默认导出(default),所以用{}接收

第二,在组件中通过Context提供的provider 将value共享出去,总组件需要用到该组件,所以暴露出去

⚠️❗context只允许我们将数据从父组件–>下层组件传递,所以将MyContext.Provider>放在外层,对按钮和文字做一个包裹,并且需要接受传入组件最为props.children,采用箭头函数的方式来接收props

export function Color = ()=> {
   return (
        <div>
     // 暂时传出去固定的默认值
            <ColorContext.Provider value={{color:'blue'}}>
                {props.children}
            </ColorContext.Provider>
        </div>
    )
}

1.2 useReducer()

官网定义如下

useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)

在某些场景下,useReducer 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递dispatch而不是回调函数

const [state,disptch]  = useReducer(reducer,initialValue)

state:状态,存储共享的状态

dispatch:派发器,🉑️用于传递action中的数据,在触发事件时就可以用到

reducer:是一个函数,接收两个参数,state和action

action中有type属性和dispatch传入的值

initialValue:默认值,可以是直接的属性名,也可以是对象的形式

我们在reducer函数🀄️简单的处理逻辑:判断是否为更新颜色,是则返回传入的action🀄️的颜色即可

const reducer = (state,action) => {
    
    switch(action.type){
        case UPDATE_COLOR:
            return action.color
        default:
            return state 
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5EMGfYme-1660268745309)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2e688e51945842afaa78a0d4bc3c4995~tplv-k3u1fbpfcp-zoom-1.image)]

blue为state中color的默认值,后面一个action打印出来的,里面会有type和color

修改一下代码

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

export const ColorContext  = createContext()
export const UPDATE_COLOR = "UPDATE_COLOR"

const reducer = (state,action) => {
    console.log(state,action);
    
    switch(action.type){
        case UPDATE_COLOR:
            return action.color
        default:
            return state 
    }
}

// props可以接收参数为组件
// 将状态中的color和dispatch作为值传出去,让需要的组件去使用,并通过派发器传入值
export const Color=(props) => {
    const [color,dispatch] = useReducer(reducer,"blue")
    return (
        <div>
            <ColorContext.Provider value={{color,dispatch}}>
                {props.children}
            </ColorContext.Provider>
        </div>
    )
}

2.Buttons.js

其中需要存放两个按钮,并给按钮添加点击事件,在事件中通过useContext传递state中的color值(后续添加了useReducer后,通过dispatch派发器向子组件传递action中的type和属性,从而改变state),这个文件中需要和color.js结合起来,比较容易理解

import React,{ useContext } from 'react';
import { ColorContext,UPDATE_COLOR } from './color';

export default function Buttons() {
    const {dispatch} = useContext(ColorContext)
    return (
        <div>
            <button onClick={()=>{dispatch({type:UPDATE_COLOR,color:'red'})}}>red</button>
            <button onClick={()=>{dispatch({type:UPDATE_COLOR,color:'yellow'})}}>yellow</button>
        </div>
    );
}

3.showArea.js

在这个组件中,只需要显示文字,并且获取对应的颜色即可

依然是用useContext()接收

import React ,{useContext}from "react";
import { ColorContext } from "./color";

function ShowArea(){
  // 使用解构赋值(ES6)新特性直接拿到color
    const {color}  = useContext(ColorContext)
    
    return (
       <div style={{color:color}}>
            <p>字体颜色为blue{color}</p>
       </div>
    )
}
export default ShowArea

4.hooks-demo.js

这个文件将组件进行组合即可

⚠️要用Color来包裹起来

import React from 'react';
import ShowArea from './showArea';
import Buttons from './Buttons';
import { Color } from './color';

export default function HooksDemo() {
    return (
        <div>
            <Color>
                <ShowArea></ShowArea>
                <Buttons></Buttons>
            </Color>
        </div>
    );
}

如果有不对的地方,欢迎指导

转载:欢迎转载,但未经作者同意,必须保留此段声明;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值