React状态管理

本文详细介绍了Redux的核心概念,包括其作为状态容器的作用、特点、工作原理以及在React项目中的应用。讲解了如何通过Redux管理数据,创建store、action和reducer,实现模块化拆分,并展示了如何通过`Provider`和`connect`解耦组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么是redux

Redux不是专门给React服务的,它是一个JavaScript应用的状态容器,提供了可预测的状态数据管理方案/管理模式,可以让开发的应用行为更为稳定且可预测,同时还可以应用于不同的环境(客户端、服务器、原生应用),并且易于测试
Redux特点

状态数据可控:状态数据按照提供的通用组件和函数完成管理,数据的CRUD操作都会被监听和同步
数据集中管理:数据集中管理实现了数据和业务的分离,方便数据项的扩展和独立维护
专业调式工具: Redux Devtools可以通过可视化方式完成数据的监控和调试
丰富社区支持:Redux有自己丰富的社区技术支持,可以和大量的第三方组件一起配合使用

项目中引入redux支持

yarn add redux

Redux核心组件

state: 初始化的数据集,主要用于集中式的存储管理的状态数据
action:数据的操作方式,主要用于区分不同的数据处理方案
reducer: 数据的具体运算,主要按照数据的处理方案,执行数据运算的部分,一般情况是一个函数

2.redux工作原理

在这里插入图片描述

3.redux基本语法

创建状态是数据管理模块: store/index.js

import {createSore} from 'redux'
initData=[{id:1,name:'华为',price:2000},{id:2,name:'苹果',price:2999}]
function goodsReducer(state=initData,action) {
	switch(action.type) {
		case 'add': 
			break
		case 'del': 
			break
		case 'edit':
			break
		default: 
			return state
	}
}
const store = createStore(goodsReducer)
export default store

数据渲染
React组件中需要引入和使用数据,数据从redux数据管理模块中进行获取和渲染

import React, { Component} from 'react'
import './layout.css'

import store from './store'
export default class Layout extends Component {
    render() {
      let goodsList = store.getState()
        return (
            <div>
                {goodsList.map(item=>
                    <h2 key={item.id}>
                        <span>id:{item.id}</span>
                        <span>商品名:{item.name}</span>
                        <span>单价:{item.price}</span>
                    </h2>
                    )}
            </div>
        )
    }
}

增加数据,编辑store/index.js

...
case 'add':
let {name,price} = action.data
let id = state.length>0 ? state[state.length-1].id+1:1
return [...state,{id,name,price}]
...
...
export default class Layout extends Component {
    state={
        goodsList:store.getState(),
        values: {
            name:'',
            price:''
        }
    }
   
    changeName=(event)=>{
        this.state.values.name = event.target.value
         this.setState({
      })
    }
    changePrice=(event)=>{
      this.state.values.price = event.target.value
      this.setState({
      })
    }
    submit=()=> {
        store.dispatch({type:'add',data:this.state.values})
        this.state.values.name = ''
        this.state.values.price = ''
        this.setState({
            goodsList:store.getState()
        })
    }
    render() {
       
        return (
            <div>
                名称:<input type="text" value={this.state.values.name} onChange={(event)=>this.changeName(event)}/>
                单价:<input type="text" value={this.state.values.price} onChange={(event)=>this.changePrice(event)}/>
                <button onClick={this.submit}>新增</button>
                {this.state.goodsList.map(item=>
                    <h2 key={item.id}>
                        <span>id:{item.id}</span>
                        <span>商品名:{item.name}</span>
                        <span>单价:{item.price}</span>
                    </h2>
                    )}
            </div>
        )
    }
}
...

编辑数据

...
case: 'edit': 
	const {id,name,price} = action.data
	let index = state.findIndex(item=>item.id === id)
	state[index].name = name
	state[index].price = price
	return state
...
export default class Layout extends Component {
    state={
        goodsList:store.getState(),
        hasId:null,
        values: {
            name:'',
            price:''
        }
    }
   
    changeName=(event)=>{
        this.state.values.name = event.target.value
         this.setState({
      })
    }
    changePrice=(event)=>{
      this.state.values.price = event.target.value
      this.setState({
      })
    }
    submit=()=> {
        if(this.state.hasId) {
            store.dispatch({type:'edit',data:{...this.state.values,id:this.state.hasId}})
        }else {
            store.dispatch({type:'add',data:this.state.values})
        }
     
        this.state.values.name = ''
        this.state.values.price = ''
        this.state.hasId = null
        this.setState({
            goodsList:store.getState()
        })
    }
    edit=(item)=>{
        console.log(item);
        this.state.values.name = item.name
        this.state.values.price = item.price
        this.state.hasId = item.id
        this.setState({})
    }
    render() {
       
        return (
            <div>
                名称:<input type="text" value={this.state.values.name} onChange={(event)=>this.changeName(event)}/>
                单价:<input type="text" value={this.state.values.price} onChange={(event)=>this.changePrice(event)}/>
                <button onClick={this.submit}>{this.state.hasId?'编辑':'新增'}</button>
              
                {this.state.goodsList.map(item=>
                    <h2 key={item.id}>
                        <span>id:{item.id}</span>
                        <span>商品名:{item.name}</span>
                        <span>单价:{item.price}</span>
                        <button onClick={()=>this.edit(item)}>编辑</button>
                    </h2>
                    )}
            </div>
        )
    }
}

删除数据

...
case 'del':
	return state.filter(goods=>goods.id!==action.data)
...
deletGoods=(id)=>{
        store.dispatch({type:'del',data:{id}})
        this.setState({
            goodsList:store.getState()
        })
    }
...
  {this.state.goodsList.map(item=>
                    <h2 key={item.id}>
                        <span>id:{item.id}</span>
                        <span>商品名:{item.name}</span>
                        <span>单价:{item.price}</span>
                        <button onClick={()=>this.edit(item)}>编辑</button>
                        <button onClick={()=>this.deletGoods(item.id)}>删除</button>
                    </h2>
                    )}
...

4.模块化拆分

1.拆cationType
actionType:数据操作方式
封装文件: goodsActionTypes.js

export const goodsAddType = 'goods/add'
export const goodsEditType = 'goods/edit'
export const goodsDelType = 'goods/del'

2.拆actionCreator
actionCreator:封装创建好的数据操作方案
封装文件: goodsActionCreator

import {goodsAddType,goodsEditType,goodsDelType} from './goodsActionTypes'
export const goodsAddAction = data=>({type:goodsAddType,data})
export const goodsEditAction = data=>({type:goodsEditType,data})
export const goodsDelAction = data=>({type:goodsDeleType,data})

封装goodsReducer
goodsReducer:数据运算函数,完成数据的具体业务处理
封装文件goodsReducer

import {goodsAddType,goodsEditType,goodsDelType} from './goodsActionTypes'
...
case goodsAddType
...
...

引入合并
goodsReducer函数已经被独立拆分到一个模块中,最终在 store/index.js中引入使用

...
import goodsReducer from './goodsReducer'
const store = createStore(brandReducer)

使用

import React, { Component} from 'react'
import './layout.css'
import { goodsAddAction,goodsEditAction,goodsDelAction } from './store/modules/actionCreator'
import store from './store'
export default class Layout extends Component {
    state={
        goodsList:store.getState(),
        hasId:null,
        values: {
            name:'',
            price:''
        }
    }
   
    changeName=(event)=>{
        this.state.values.name = event.target.value
         this.setState({
      })
    }
    changePrice=(event)=>{
      this.state.values.price = event.target.value
      this.setState({
      })
    }
    submit=()=> {
        if(this.state.hasId) {
            // store.dispatch({type:'edit',data:{...this.state.values,id:this.state.hasId}})
            store.dispatch(goodsEditAction({...this.state.values,id:this.state.hasId}))

        }else {
            // store.dispatch({type:'add',data:this.state.values})
            store.dispatch(goodsDelAction(this.state.values))
        }
     
        this.state.values.name = ''
        this.state.values.price = ''
        this.state.hasId = null
        this.setState({
            goodsList:store.getState()
        })
    }
    edit=(item)=>{
        console.log(item);
        this.state.values.name = item.name
        this.state.values.price = item.price
        this.state.hasId = item.id
        this.setState({})
    }
    deletGoods=(id)=>{
        // store.dispatch({type:'del',data:{id}})
        store.dispatch(goodsDelAction({id}))
        this.setState({
            goodsList:store.getState()
        })
    }
    render() {
       
        return (
            <div>
                名称:<input type="text" value={this.state.values.name} onChange={(event)=>this.changeName(event)}/>
                单价:<input type="text" value={this.state.values.price} onChange={(event)=>this.changePrice(event)}/>
                <button onClick={this.submit}>{this.state.hasId?'编辑':'新增'}</button>
              
                {this.state.goodsList.map(item=>
                    <h2 key={item.id}>
                        <span>id:{item.id}</span>
                        <span>商品名:{item.name}</span>
                        <span>单价:{item.price}</span>
                        <button onClick={()=>this.edit(item)}>编辑</button>
                        <button onClick={()=>this.deletGoods(item.id)}>删除</button>
                    </h2>
                    )}
            </div>
        )
    }
}

5.多模块开发

redux提供了combineReducer用于将多个拆分管理的数据模块,最终合并多个模块

import {combineReducers} from 'redux'
const store = createStore(combineReducers({
	goods:goodsReducer,
	orders:ordersReducer
}))
import React, { Component} from 'react'
import './layout.css'
import { goodsAddAction,goodsEditAction,goodsDelAction } from './store/modules/actionCreator'
import store from './store'
export default class Layout extends Component {
    state={
        goodsList:store.getState().goods,
        hasId:null,
        values: {
            name:'',
            price:''
        }
    }
   
    changeName=(event)=>{
        this.state.values.name = event.target.value
         this.setState({
      })
    }
    changePrice=(event)=>{
      this.state.values.price = event.target.value
      this.setState({
      })
    }
    submit=()=> {
        if(this.state.hasId) {
            // store.dispatch({type:'edit',data:{...this.state.values,id:this.state.hasId}})
            store.dispatch(goodsEditAction({...this.state.values,id:this.state.hasId}))

        }else {
            // store.dispatch({type:'add',data:this.state.values})
            store.dispatch(goodsAddAction(this.state.values))
        }
     
        this.state.values.name = ''
        this.state.values.price = ''
        this.state.hasId = null
        this.setState({
            goodsList:store.getState().goods
        })
    }
    edit=(item)=>{
        console.log(item);
        this.state.values.name = item.name
        this.state.values.price = item.price
        this.state.hasId = item.id
        this.setState({})
    }
    deletGoods=(id)=>{
        // store.dispatch({type:'del',data:{id}})
        store.dispatch(goodsDelAction({id}))
        this.setState({
            goodsList:store.getState().goods
        })
    }
    render() {
       
        return (
            <div>
                名称:<input type="text" value={this.state.values.name} onChange={(event)=>this.changeName(event)}/>
                单价:<input type="text" value={this.state.values.price} onChange={(event)=>this.changePrice(event)}/>
                <button onClick={this.submit}>{this.state.hasId?'编辑':'新增'}</button>
              
                {this.state.goodsList.map(item=>
                    <h2 key={item.id}>
                        <span>id:{item.id}</span>
                        <span>商品名:{item.name}</span>
                        <span>单价:{item.price}</span>
                        <button onClick={()=>this.edit(item)}>编辑</button>
                        <button onClick={()=>this.deletGoods(item.id)}>删除</button>
                    </h2>
                    )}
            </div>
        )
    }
}

6.解耦合

React项目中使用Redux管理状态数据,导致组件中出现了大量store.method调用方式,让两个不同技术之间的代码的耦合度太高,不利于后期项目的维护
react提供了一个模块:react-redux,转么用于解耦合react组件,redux状态管理模式

Provider: 提供者的意思,提供数据管理桥梁,让redux中的数据可以在react组件中按照固定语法直接使用,避免大量的代码耦合
固定语法:将Provider组件包裹在React应用的根组件外部

import Provider from 'react-redux'
import store './store/index'
function() {
	return <Provider store={store}>
	其他组件
	</Provider>
}

connect() ,用于管理指定的组件,映射数据state和操作方案action
固定语法:将默认组件的导出方式,连接到数据和操作的映射关系上

import {connect} from 'react-redux'
export default connect(映射state数据,映射action函数)(goods)

代码操作
安装react-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值