5分钟上手redux

3 篇文章 0 订阅

Redux详解

Redux介绍

Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理。

在Redux中有3个原则

  • 单一数据源

    整个应用的State被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个Stroe中。

  • State 是只读的

    唯一改变State 的方法就是触发ActionsActions是一个用于描述已发生事件的普通对象。

  • 使用纯函数来执行修改

    为了描述Actions如何改变 State tree ,你需要编写 Reducers

如下图所示,在Redux中,有一个全局状态存储器Store,只有Actions才能去进行修改Store中的数据,其更改数据这一过程,即store.dispatch(action)就是为Reducers。当Actions修改完Store中的数据后,Store会通知对应页面其数据发送改变。

img

Redux有什么作用

得益于react是单项数据流的关系,在react框架中要统筹全局数据就显得较为繁琐,需要通过父子间的组件传递/或者是Context才能进行跨组件交流,但在react里,context是个反模式的东西,不同于redux等的细粒度响应式更新,context的值一旦变化,所有依赖该context的组件全部都会force update,因为context API并不能细粒度地分析某个组件依赖了context里的哪个属性,并且它可以穿透React.memoshouldComponentUpdate的对比,把所有涉事组件强制刷新。

Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。

如何在React中使用Redux

React中使用的是react-redux这个三方包

这里借用下大佬绘制的流程图,大致流程如下

在这里插入图片描述

react-redux中的connect方法将store上的getState 和 dispatch 包装成组件的props。

如何使用React-redux

举个todoList的栗子

在需要共享数据的主入口,先引入reduxreact-redux,再引入 createStore 来创建组件共享的数据,这个是 redux 中提供的一个方法,我们直接引入,并将主入口文件用Provider包裹一下。

import React, { Component } from 'react';
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import reducer from './redux/reducer/index'
import AddItemPage from './components/index'
const store = createStore(reducer)  //使用createStore创建个store
export default class App extends Component {
  render() {
    return (<Provider store={store}>  //todoList共享store
      <AddItemPage/> //todoList页面
    </Provider>)
  }
}

然后去定义actionreducer的初始状态,因为在reducer中已经设置了state的初始值为[],故不作定义state

reducer的

import { combineReducers } from 'redux'
​
const addItem = (state = [], action) => {
    switch (action.type) {
      case 'ADD_ITEM':
        return [
          ...state,
          {
            id: action.id,
            text: action.text,
            isDelete: false
          }
        ]
      case 'DELETE_ITEM':
        let newState = [...state]
        console.log(newState)
        action.id.map(item=>{
          newState.splice(item.id,1)
        })
        return newState
      default:
        return state
    }
  }
  
export default combineReducers({
    addItem
})
​
  

action

let nextItemId = 0
export const addTodo = text => ({
  type: 'ADD_ITEM',
  id: nextItemId++,
  text
})
​
export const deleteItem = id => ({
  type: 'DELETE_ITEM',
  id
})

然后再模块中将定义的action以及reducer返回的state链接到模块中

import React, { Component } from 'react';
import { connect } from 'react-redux'
import { addTodo,deleteItem } from '../redux/action'
import ItemList from './itemList'
​
class AddItem extends Component {
    render() {
        const { addItem,doAdd,doDelete } = this.props
        return  <>
        <div>
            <form onSubmit={e => {
            e.preventDefault()
            if (!this.input.value.trim()) {
                return
            }
            doAdd(this.input.value)
            // this.props.dispatch(addTodo(this.input.value))
            this.input.value = ''
            }}>
            <input ref={node => this.input = node} />
            <button type="submit">
                添加
            </button>
            <button type="button" onClick={(e)=>{
                let arr = []
                const checkbox = document.getElementsByName('itemId').forEach(item=> {
                if(item.checked) arr.push(item.value)
                })
                doDelete(arr)
                // this.props.dispatch(deleteItem(arr))
                }}>
                删除
            </button>
            </form>
    </div>
    <ItemList addItem={addItem}/>
    </>
  }
}
const mapStateToProps = state => {return ({...state})}
const mapDispatchToProps = dispatch => ({
    doAdd:(value)=>dispatch(addTodo(value)),
    doDelete:(arr)=>dispatch(deleteItem(arr))
})
​
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(AddItem)
​
import React, { Component } from 'react';
class itemList extends Component {
  render() {
    return <>
    {
      this.props.addItem.map(item=>{
          return <div  key={item.id} {...item}>
            <input type='checkbox' name='itemId' value={item?.id}/>
              <li
              style={{
                textDecoration: item?.completed ? 'line-through' : 'none'
              }}
            >
              {item?.text}
            </li>
          </div>
        })
    }
    </>;
  }
}
​
export default itemList

即可,

可以看到输入123,点击添加的时候触发了ADD_ITEM的操作

在这里插入图片描述

点击删除的时候触发了DELETE_ITEM操作

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值