React Hooks之useReducer

2023-10-18 22:12
文章标签 react hooks usereducer

本文主要是介绍React Hooks之useReducer,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、useReducer

const [state, dispatch] = useReducer(reducer, initialArg, init?)
  • useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。
  • 数据结构简单用useState,复杂时用useReducer
  • 简化版的redux
  • 结合context解决跨组件的问题
  • state dispatch默认没有模块化,数据混在一起

  • state或store:数据
  • action:命令
  • reducer: 规定,根据action的type做相应处理返回新的state
  • dispatch: 派发action

二、基本使用

CounterReducer.tsx

// import React, { FC, useState } from 'react' //注释的是使用useState的情况
import React, { FC, useReducer } from 'react'type StateType = { count: number }
type ActionType = { type: string }const initialState: StateType = { count: 100 } // 初始值100// 根据传入的action 返回新的state(不可变数据)
function 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 CountReducer:FC = () => {// const [count, setCount] = useState(100)const [state, dispatch] = useReducer(reducer, initialState)return (// <>//   <p>coint: {count}</p>//   <button onClick={() => setCount(count + 1)}>+</button>//   <button onClick={() => setCount(count - 1)}>-</button>// </><><p>coint: {state.count}</p><button onClick={() => dispatch({ type: 'increment' })}>+</button><button onClick={() => dispatch({ type: 'decrement' })}>-</button></>)}export default CountReducer

三、Todo List By useReducer项目

在这里插入图片描述
使用Context和useReducer实现跨组件通讯
代码地址:点击跳转

store.ts
在这里插入图片描述
reducer.tsx
在这里插入图片描述
List.tsx

import React, { FC, useContext } from 'react'
// import reducer from './reducer'
// import initialState from './store'
import { TodoContext } from '.'const List:FC = () => {// const [state, dispatch] = useReducer(reducer, initialState)// const [state, dispatch] = useReducer(reducer, initialState)const context = useContext(TodoContext)const { state, dispatch } = contextconst del = (id: string) => {dispatch({type: 'delete',payload: id})}return (<><p>list</p><ul>{state.map(item => {return <li key={item.id}><span>{item.title}</span><button onClick={() => del(item.id)}>删除</button></li>})}</ul></>)}export default List

InputForm.tsx

import React, { FC, ChangeEvent, useState, useContext } from 'react'
// import reducer from './reducer'
// import initialState from './store'
import { nanoid } from 'nanoid'
import { TodoContext } from '.'const InputForm:FC = () => {// const [state, dispatch] = useReducer(reducer, initialState)const context = useContext(TodoContext)const { state, dispatch } = context// 输入框文字const [text, setText] = useState('')const handleChange = (event: ChangeEvent<HTMLInputElement>) => {setText(event.target.value)}// 新增todoconst handleSubmit = (event: ChangeEvent<HTMLFormElement>) => {event.preventDefault()if (!text.trim()) returnconst newTodo = {id: nanoid(5),title: text}dispatch({type: 'add',payload: newTodo})setText('')}return (<form onSubmit={handleSubmit}><label htmlFor="new-todo">what needs to be done?</label><br /><input id='new-todo' onChange={handleChange} value={text} /><button type='submit'>Add #{state.length + 1}</button></form>)}export default InputForm

index.tsx

import React, { FC, createContext, useReducer } from 'react'
import List from './List'
import InputForm from './InputForm'
import reducer, { ActionType } from './reducer'
import initialState from './store'export const TodoContext = createContext({state: initialState,// eslint-disable-next-linedispatch: ( action: ActionType ) => {/* 空 */}
})const Demo:FC = () => {const [state, dispatch] = useReducer(reducer, initialState)return (<TodoContext.Provider value={{ state, dispatch }}><p>Todo list by reducer</p><List /><InputForm /></TodoContext.Provider>)}export default Demo

这篇关于React Hooks之useReducer的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/235442

相关文章

Nginx部署React项目时重定向循环问题的解决方案

《Nginx部署React项目时重定向循环问题的解决方案》Nginx在处理React项目请求时出现重定向循环,通常是由于`try_files`配置错误或`root`路径配置不当导致的,本文给大家详细介... 目录问题原因1. try_files 配置错误2. root 路径错误解决方法1. 检查 try_f

在React聊天应用中实现图片上传功能

《在React聊天应用中实现图片上传功能》在现代聊天应用中,除了文字和表情,图片分享也是一个重要的功能,本文将详细介绍如何在基于React的聊天应用中实现图片上传和预览功能,感兴趣的小伙伴跟着小编一起... 目录技术栈实现步骤1. 消息组件改造2. 图片预览组件3. 聊天输入组件改造功能特点使用说明注意事项

在React中引入Tailwind CSS的完整指南

《在React中引入TailwindCSS的完整指南》在现代前端开发中,使用UI库可以显著提高开发效率,TailwindCSS是一个功能类优先的CSS框架,本文将详细介绍如何在Reac... 目录前言一、Tailwind css 简介二、创建 React 项目使用 Create React App 创建项目

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

js react 笔记 2

起因, 目的: 记录一些 js, react, css 1. 生成一个随机的 uuid // 需要先安装 crypto 模块const { randomUUID } = require('crypto');const uuid = randomUUID();console.log(uuid); // 输出类似 '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

React 笔记 父子组件传值 | 父组件调用子组件数据 | defaultProps | propsType合法性验证

1.通过props实现父组件像子组件传值 、方法、甚至整个父组件 传递整个父组件则   [变量名]={this} import Header from "./Header"render(){return(<Header msg={"我是props传递的数据"}/>)} import React,{Component} from "react";class Header extends

react笔记 8-21 约束性 表单

1、约束性组件和非约束性组件 非约束性组件<input type="text" name="" defaultValue={this.state.msg}></input>这里他的value是用户输入的值 并没有执行操作 只是获取到了msg的值 用户输入不会改变数据非约束性组件需要使用defaultValue获取数据 否则会报错约束性组件<input type="text

react笔记 8-19 事件对象、获取dom元素、双向绑定

1、事件对象event 通过事件的event对象获取它的dom元素 run=(event)=>{event.target.style="background:yellowgreen" //event的父级为他本身event.target.getAttribute("aid") //这样便获取到了它的自定义属性aid}render() {return (<div><h2>{

react笔记 8-18 事件 方法 定义方法 获取/改变数据 传值

1、定义方法并绑定 class News extends React.Component {constructor(props) {super(props)this.state = {msg:'home组件'}}run(){alert("我是一个run") //方法写在类中}render() {return (<div><h2>{this.state.msg}</h2><button onCli