redux和React-Redux的基本使用

Posted 劳埃德·福杰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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读取和操作状态

以上是关于redux和React-Redux的基本使用的主要内容,如果未能解决你的问题,请参考以下文章

React入门之Redux:react-redux基本使用

React入门之Redux:react-redux基本使用

react-redux基本使用

react-redux基本使用

Redux 入门教程:React-Redux 的用法

react-redux入门教程