Redux知识总结一(一篇就能搞明白redux的用法)

Redux知识总结一(一篇就能搞明白redux的用法)

一、什么是Redux?

官网:Redux 是 JavaScript应用的状态容器,提供可预测化的状态管理;

  1. Javascript应用:是指任何Javascript构建的项目,而不是仅仅是React框架构建的项目,当然他们搭配用起来更加顺手;
  2. 状态容器:react项目中的state抽离出来集中在对象树状结构中store(状态容器),一个项目只能有一个store(状态容器);
  3. 可预测性:对于状态的更新变化都是通过纯函数进行操作的,纯函数的核心就是不管传入什么参数,都不会影响改变你传入参数的值;也就是每个新的state都会在旧的state进行产生,而且还不改变旧的state,这就是可预测性;

总结:redux是基于facebooke的flux架构建立的框架,因为flux数据只能在一个方向流动的特性(单向性),数据的流向就是Model(State)->view;Flux架构图如下:

注意:一个项目中一般只有一个store(状态容器),项目中所有的state都集中在store中进行管理;

二、为什么用Redux?

先谈谈react,react是由facebook公司开源的前端框架;主要用于构建前端界面,将项目中的前端界面进行组件化处理,也就是说react是解决DOM层面上的抽象层;对于一个完整的前端项目来说,这样是仅仅不够的,它并没有很好的解决组件之间的通信,只通过形式props实现了简单结构的组件通信,对于复杂结构的组件,如果进行采用props形式实现通信,会使整个项目变得难以维护,项目结构混乱;因此诞生出了另一套解决方案:基于Flux架构实现的Redux状态管理框架;

Redux知识介绍:
  1. “工欲善其事必先利其器”,在介绍Redux之前,先用create-react-app脚手架工具搭建出基本的react项目;

create-react-app介绍链接:https://github.com/facebook/create-react-app

  1. 如果对React不熟的小伙伴可以参考以下链接学习;

react学习链接:https://zh-hans.reactjs.org/tutorial/tutorial.html

准备好以上知识点,就可以开始我们的Redux之旅了;在这先了解下纯函数

纯函数:是指在函数中只依赖其参数,并且不会改变所传入的参数,也就是没有副作用的情况下称之为纯函数;代码如下:

    /**
    **案例一:函数不止依赖于函数参数
    **不属于纯函数,setName函数引用了外部变量age,
    **不符合“只依赖参数”这个条件
    **/
    var name="张三";
    var age=26;
    function setName(name){
        str="姓名:"+name+";年龄:"+age;
        return str;
    }
    setName(name);
    /**
    **案例二:改变外部环境,产生副作用
    **不属于纯函数,setName函数改变了外部变量name的
    **的,也就是影响了外部环境,产生了副作用;
    **/
    var name="张三";
    function setName(name){
        name="李四";
        console.log(name);
        return name;
    }
    setName(name);
    //纯函数来了
    var name="张三";
    function setName(name){
        var newName=name;
        newName="李四";
        return newName;
    }
    setName(name);

redux化繁为简学习:

1、基本了解redux运作机制

redux中state属于状态容器,用来存放相应的数据状态,然后在自定义Action规则,它是把数据从应用传到 store 的有效载荷。属于 store 数据的唯一来源。你可以通过 store.dispatch() 将 action 传到 store。执行reducer纯函数进行数据状态更改;其中store是将它们连接起来的概念化的标识;redux具体运行机制如下图所示:
先了解redux基本运行机制图解。如图所示:

2、利用readux实现标签动态增减

1.通过create-react-app搭建基本项目结构,并通过yarn add redux命令安装redux npm包(cnpm install --save redux)也可以安装,完善项目基本结构;如下图示:
在这里插入图片描述
2.利用Action创建函数创建相应的Action,actions.js文件代码如下所示:(Action部分)

/**redux/actions.js文件代码**/
const ADD_TAG="TAG_ADD";
const DEL_TAG="TAG_DEL";

//新增标签Action
export const addTag=(payload)=>{
  return {
    type:ADD_TAG,
    payload:payload
  }
}
//移除标签Action
export const delTag=()=>{
  return {
    type:DEL_TAG
  }
}

3.定义标签初始数据状态,state.js文件代码如下所示:(state部分)

/**redux/state.js文件代码**/
export const InitTagState=[{
  "id":"001",
  "name":"标签一"
}];

4.使用纯函数模式创建reducer处理机(个人认为它就是处理state的处理机),reducer.js文件如下所示:(reducer部分)

/**redux/reducer.js文件代码**/
import {initTagState} from "./state";
import {ADD_TAG,DEL_TAG} from "./actions";

export const TagReducer=(state=initTagState,data)=>{
  let new_arr=[];
  new_arr=[].concat(state);
  switch(data.type){
    case ADD_TAG: //新增标签
      new_arr.push(data.payload);
      return new_arr;
    case DEL_TAG: //删除标签
      new_arr.splice(0,1);
      return new_arr;
    default:
      return new_arr;
  }
}

5.到这里redux系统架构基本完成了,接下来就需要将它们关联起来形成概念化的store了;index.js代码如下

import {createStore,combineReducers} from "redux";
import {TagReducer} from "./reducer";

/*
 * 多个reducer汇总的写法(注释区域)
 * 需要用combineReducers方法关联形成一个大的reducer
 * 只有一个就没有必要用combineReducers方法
 */
// const allReducers={
//   tInfo:TagReducer,
//   //...
// }
// const reducers=combineReducers(allReducers);
// const store=createStore(reducers);

/*单个写法*/
const store=createStore(TagReducer);
export default store;

6.最终篇,只要通过subscribe方法,将redux与项目主入口文件index.js关联起来即可;根目录下index.js文件代码如下:(index.js属于项目入口文件)

/*根目录中index.js文件*/
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from "./redux";

const render=()=>{
  ReactDOM.render(<App />, document.getElementById('root'));
};
render();
const unsubscribe=store.subscribe(()=>{
  render();
});

serviceWorker.unregister();

7.组件功能实现文件App.js,代码如下:(App.js属于组件入口文件)

import React, { Component } from 'react';
import store from "./redux";
import {addTag,delTag} from "./redux/actions";
import './App.css';

class App extends Component {
  addTagFuns=()=>{
    const obj={
      "name":"标签二"
    };
    store.dispatch(addTag(obj));
  }
  delTagFuns=()=>{
    store.dispatch(delTag());
  }
  render() {
    const tag_list=store.getState();
    let tag_com=tag_list.map((item)=>{
      return (<span class="tag">{item.name}</span>);
    })
    return (
      <div className="App">
        <div>
          <button type="button" onClick={this.addTagFuns}>新增标签</button>
          <button type="button" onClick={this.delTagFuns}>删除标签</button>
        </div>
        {tag_com}
      </div>
    );
  }
}

export default App;

subscribe(funs)这个函数是用来去订阅 store 的变化,你每次对store进行 dispatch(action) 都会触发 subscribe 注册的函数调用,这个在实际情况不是必须要的,看自己的应用场景,如果你想store变化后view视图也要跟着变化,那么就需要全局订阅store变化;

猜你喜欢

转载自blog.csdn.net/u012475786/article/details/88974145