Hooks demo
1️⃣
最近在做vue无缝衔接react项目的准备,就找了个react中灰常重要❕🉐️Hooks的小练习来训练一下
前情提要:你需要优先学习html、css、js(👀特别是ES新特性)或者学习过Vue.js😉
不然学起react来,还是会比较吃力😩,因为我即使是上面几样都学过,也会觉得react有点难度(毕竟是普遍认为最难的框架)
✌️开始吧
今天的案例来自B站技术胖老师的教程,感兴趣的朋友直接去看视频,以下内容搭配了自己的理解
点击按钮改变文字颜色
构建4个组件
- 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.memo 或 shouldComponentUpdate,也会在组件本身使用 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
}
}
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>
);
}
如果有不对的地方,欢迎指导
转载:欢迎转载,但未经作者同意,必须保留此段声明;