redux和React-Redux的基本使用

目录

1.简介

redux是一个专门用于状态管理的JS库,可用在React、Vue、Angular等项目中。

什么情况下要用到redux?
①某个组件的状态,需要让其它组件拿到(共享)。
②一个组件需要改变另一个组件的状态(通信)。

redux工作流程

Action:是一个普通JS对象,type字段用于描述发生事件的类型,payload字段用于描述发生的具体事情。
Action Creator:是一个创建并返回一个 action 对象的函数。
Reducer:是一个函数,接收当前的state和action对象,必要时决定如何更新状态,并返回新状态,可以将 reducer 视为一个事件监听器。
Store:当前 Redux 应用的 state 存在于一个名为 store 的对象中。store 是通过传入一个 reducer 来创建的,并且有一个名为getState的方法,它返回当前状态值。
dispatch:store有一个方法叫dispatch。更新 state 的唯一方法是调用store.dispatch()并传入一个action对象。store 将执行所有 reducer 函数并计算出更新后的 state,调用getState()可以获取新 state。dispatch一个action可以形象的理解为 "触发一个事件"。

React-Redux 是 React 的官方 Redux UI 绑定库。如果想要同时使用 Redux 和 React,你也应该使用 React-Redux 来绑定这两个库。 

UI组件应该包裹一个容器组件,它们是父子关系。
UI组件不能使用任何redux的api,只负责页面的呈现和交互,容器组件负责和redux通信,容器组件可以传给UI组件:redux中保存的状态和用于操作状态的方法。

2.求和案例(纯React版本)

/public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <title>Redux</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

/src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

/src/App.jsx

import Count from "./components/Count";

function App() {
  return (
    <div>
      <Count />
    </div>
  );
}

export default App;

 /src/components/Count/index.jsx

import React, { Component } from 'react'

export default class Count extends Component {

  state = {count:0}

  increment=()=>{
    const {value} = this.selectNumer
    const {count} = this.state
    this.setState({count:count+value*1})
  }

  decrement=()=>{
    const {value} = this.selectNumer
    const {count} = this.state
    this.setState({count:count-value*1})
  }

  incrementAsync=()=>{
    const {value} = this.selectNumer
    const {count} = this.state
    setTimeout(() => {
      this.setState({count:count+value*1})
    }, 500)
  }

  render() {
    return (
      <div>
        <h1>当前求和为:{this.state.count}</h1>
        <select ref={c => this.selectNumer = c}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>&nbsp;
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>&nbsp;
      </div>
    )
  }
}

3.求和案例(redux版本)

npx create-react-app redux-demo //新建项目
npm install @reduxjs/toolkit

/src/components/Count/index.jsx 

import React, { Component } from 'react'
import store from '../../redux/store'
import { createIncrementAction,createDecrementAction,createIncrementAsyncAction } from '../../redux/count_action'

export default class Count extends Component {

  increment=()=>{
    const {value} = this.selectNumer
    store.dispatch(createIncrementAction(value*1))
  }

  decrement=()=>{
    const {value} = this.selectNumer
    store.dispatch(createDecrementAction(value*1))
  }

  incrementAsync=()=>{
    const {value} = this.selectNumer
    store.dispatch(createIncrementAsyncAction(value*1,500))
  }

  render() {
    return (
      <div>
        <h1>当前求和为:{store.getState()}</h1>
        <select ref={c => this.selectNumer = c}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>&nbsp;
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>&nbsp;
      </div>
    )
  }
}

/src/redux/constant.js

/*
  该模块用于定义action对象中type类型的常量值
*/
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

/src/redux/count_action.js

/*
  该文件专门为Count组件生成action对象
*/
import { INCREMENT, DECREMENT } from "./constant";

// 同步action,就是指action的值为一般object类型的对象
export const createIncrementAction = data => ({type:INCREMENT,payload: data})
export const createDecrementAction = data => ({type:DECREMENT,payload: data})

// 异步action,就是指action的值为函数
export const createIncrementAsyncAction = (data, time) => {
  return (dispatch)=>{
    setTimeout(()=>{
      dispatch(createIncrementAction(data))
    },time)
  }
}

/src/redux/store.js

/*
  该文件用于暴露一个store对象
*/
import {configureStore} from '@reduxjs/toolkit'
import countReducer from './count_reducer'

export default configureStore({ reducer: countReducer })

/src/redux/count_reducer.js

/*
  该文件是用于创建一个为Count组件服务的reducer
*/
import { INCREMENT,DECREMENT } from "./constant";

const initState = 0;
export default function countReducer(preState=initState, action) {
  const {type, payload} = action;
  switch(type) {
    case INCREMENT:
      return preState+payload;
    case DECREMENT:
      return preState-payload;
    default:
      return preState;
  }
}

/src/App.jsx同上

/src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from './redux/store';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
// 添加一个变化监听器, 每当dispatch action的时候就会执行
store.subscribe(()=>{
	root.render(<App />);
})

效果同上

4.求和案例(react-redux版本)

npm install react-redux

/src/components/Count/index.jsx文件删掉,换成/src/containers/Count/index.jsx

import {connect} from 'react-redux'
import React, { Component } from 'react'
// 引入action
import {
  createIncrementAction,
  createDecrementAction,
  createIncrementAsyncAction
} from '../../redux/count_action'

// 定义CountUI组件
class CountUI extends Component {

  increment=()=>{
    const {value} = this.selectNumer
    this.props.add(value*1)
  }

  decrement=()=>{
    const {value} = this.selectNumer
    this.props.subtract(value*1)
  }

  incrementAsync=()=>{
    const {value} = this.selectNumer
    this.props.addAsync(value*1,500)
  }

  render() {
    return (
      <div>
        <h1>当前求和为:{this.props.count}</h1>
        <select ref={c => this.selectNumer = c}>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>&nbsp;
        <button onClick={this.increment}>+</button>&nbsp;
        <button onClick={this.decrement}>-</button>&nbsp;
        <button onClick={this.incrementAsync}>异步加</button>&nbsp;
      </div>
    )
  }
}

// 创建并暴露一个Count的容器组件
export default connect(
  state => ({count: state}), 
  {
    add: createIncrementAction,
    subtract: createDecrementAction,
    addAsync: createIncrementAsyncAction
  }
)(CountUI)

redux下面的四个文件不变,同上 

/src/App.jsx同上

/src/index.js(index.js中不用监测了,容器组件会自动监测)

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from './redux/store';
import { Provider } from 'react-redux';  // provider会自动帮容器组件传store

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
	<Provider store={store}>
		<App />
	</Provider>
);

效果同上

小结:
一个组件要和redux“打交道”要经过哪几步?

①.定义好UI组件---不暴露
②.引入connect生成一个容器组件,并暴露,写法如下:

connect(
    state => ({key:value}), //映射状态
    {key:xxxxxAction} //映射操作状态的方法
)(UI组件)

③在UI组件中通过this.props.xxxxxxx读取和操作状态

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漂流の少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值