周大胖子 发表于 2020-11-19 17:22:33

React 的 redux 重新学习[前面学废了]

本帖最后由 周大胖子 于 2020-11-25 16:31 编辑

加深理解:
      react是 ui 层的框架 ,不适合开发大型项目,为此有了 redux 这个数据层的框架 ;
      redux = Reducer + Flux[这个是最原始层的react数据层框架] ;
      问我为啥要知道这个:我怕哪天HR装逼的问我,我好回答他。

开始理使用模式:    一、安装篇:
      1. 安装 redux
                cnpminstall --save redux

      2. 安装 redux-thunk   【使用这个中间件的主要目的,就是为了异步请求而已,他能让store接收的action 不仅有json 对象,还可以接收函数,前期知道就行,后期无脑复制框架】
               cnpm install --save redux-thunk

      3. 看有没有自己安装过 axios, 没有也安装一下[就是异步请求用滴,我不信你用不到 嘿嘿]

               cnpm install --save axios


   二、 开始布局:
         首先,要明白 :除了模块外 一共是四个文件,你可以放一个文件夹里,就 src/store/。叫啥名其实随意 ,
         1. Store.js   -> 核心文件,仓库
         2. Reducer.js-> 核心文件 ,仓库管理员
         3. ActionTypes.js-> 辅助文件 , 仓库管理员的 小本本,【个人说明这玩意的存在价值主要是为了,方便报错】
         4. ActionCreator.js-> 核心文件, 仓库管理员的操作手册

   二、了解ation.[ 不了解也没关系,通篇结束了 再回来看也行 ]

      5. action 的构造,注意了 所有接收派发的 action 都是一样的格式
               { type:'add_menu_list', value:'------' }   这个value 可以换掉键值对,只要action 接收的一样就行

      6. action的接收位置只有一个地方,那就是 Reducer.js 的 函数中。[ 不要复制只做理解 ]
export default (state = defaultState, action) => {
                console.log(action)

               if (action.type === 这里写action的type ,当然后来写ActionTypes声明的值 ) {

                }

             return state;
         };

               
============================================================走起来吧我的大胸弟=========
    三、 走逻辑开始用文件:
         3.1. 先造一个仓库,且使用redux-thunk [就是新建Store.js 文件,这里我直接上最终成品代码 ]// 第一步利用 redux 中的 createStore 来创建 一个仓库
import { createStore, applyMiddleware } from 'redux';
import reducer from './Reducer';
import thunk from 'redux-thunk';// 这是redux 的中间件! 不是react的中间件

// 第二步 是引入 且 成功搞一个 仓库操作的类[可以看做图书管理员所使用的电脑软件]
// const store = () => createStore(reducer, applyMiddleware(thunk));
// 这句话 如此高端,可是对store来说,如果我在 模块中使用store.getState(); 会报错 报没有这个方法

// 这句话的意思是这样的:创建含有中间件thunk 的 store
// applyMiddleware(thunk)
const store = createStore(
    reducer,
    applyMiddleware(thunk)

);


export default store;[ 这里的reduer,已经是创建好的了,我也是为了方便复制,如果报错不要急,下一步就是创建 reducer ];

=======
   3.2.有了仓库,得有仓库管理员 [ 就是新建Reducer.js 文件。同样直接上最终码 ]
// 投入项目生产中的,这是一个处理器 用来 对 store进行对应的操作;

// 引入action.type ,这里是为了判断
import { GetNewsList } from './ActionTypes';
// import { actionGetNewsList } from './ActionCreator';



const defaultState = {
    inpValue: '123',
    arr: [],
    newsArr: [{
      'title': 'iPhone用户的福利:连苹果都望尘莫及的APP',
      'url': 'http://www.baidu.com/',
      'author': '老莫',
      'addtime': '2020-09-03',
      'introduction': '副标题#e# 无论是iPhone用户,亦或是安卓用户,应用程序都是智能手机不可或缺的一个组成部分。尤其是对于iPhone用户而言,苹果的App Store里不乏出众的应用可供选择。有些甚至比苹果公司自己开发的应用还要好。 如果你想让自己的iPhone充分发挥它的优势。'
    }],
};

// reducer只能接收 不能修改 store
export default (state = defaultState, action) => {
    console.log(action)

    // if (action.type == 'chang_inp_value') {
    //   
    // }

    if (action.type === GetNewsList) {

      // 这个步骤,视频里 说是拷贝,对json 的 解析 属于脱裤子放屁的 “深拷贝”
      let newState = JSON.parse(JSON.stringify(state));

      // console.log(action.data) 这是除了type 传回来的值

      newState.newsArr = action.data.data.data;

      return newState;
    }

    return state;
};   如果,当然 你还没有创建管理员的小本本,就是 ActionTypes.js ,继续报错 别急。我们来创建小本本

======
    3.3 创建管理员的小本本,错的时候知道在哪错了[ 就是 ActionTypes.js 文件,里面全是 action.type 的type   ]
// 在这里 把所有的 action.type 都 写出来
// 然后在 - Reducer.js -- ActionCreator.js - 引用
// 这个文件存在的意义 就是为了报错。
export const GetNewsList = 'get_news_list';
export const ChangInpValue = 'chang_inp_value';这里的type 得无限添加 。你用啥自己添加

=============
3.4 最后开始创建管理员的操作手册[ 就是ActionCreator.js ,这个文件的意义,就是按照逻辑,得到或处理数据,异步调用也在这里。 然后通过 把处理完的数据,再 通过action 还给 Reducer.js, 很绕。但是别担心复制我这个就行]
// 这个文件主要用来统一管理 action
// 引入action.type
import { GetNewsList } from './ActionTypes';
import axios from 'axios';

// 把异步请求的域名提出来,根据自己的需求或者生产环境进行修改
const webServer = 'http://www.newadmin.com/';

// 最古老的的形式 ,连 ActionTypes 都没用
// export const actionChangInpValue = (value) => ({
//   type: "chang_inp_value",
//   value: value

// });

// export const actionChangList = (index) => ({
//   type: 'chang_list'
//         // ,index
// })


// 新闻列表的action
export const actionGetNewsList = (JsonData) => ({
    type: GetNewsList,
    data: JsonData
})

// 使用redux-thunk 返回值可以是一个函数, 如果没有使用 返回值只能是个json
export const funGetNewsList = () => {
    // 返回的函数会自动接收到 dispatch 对象
    return (dispatch) => {
      axios.get(webServer + 'getNews').then((res) => {
            let data = res.data;
            // console.log(res);
            // 派发action
            dispatch(actionGetNewsList(data));
      })
    }
}这次应该不会报错了。哈哈。 一般进ActionCreator.js 中,      3.4.1 如果不涉及到 异步调用,则无需使用这个 funGetNewsList 这种返回函数对象的流程。而是直接使用actionGetNewsList搞一个简单的Action;      3.4.2 若使用 异步请求,对接收到的数据进行处理,那么 在ActionCreator.js 中。 得设置两个,一个负债 接收且处理函数,接收完之后,通过 自动接收的 dispatch函数,再次派发action

===== 3.5 终于到了激动人心的 模块怎么写时刻:
   3.5.1 在模块中 引入仓库和操作手册:操作手册按需引入其中的函数或action。
import store from '../../store/Store';
import { funGetNewsList } from'../../store/ActionCreator';


3.5.2 在模块中 利用store.getState(); 这个仓库自带的方法获取仓库中的数据:
    constructor(props){
      super(props);
      this.state = store.getState();
      // console.log(this.state);
      
// 这是订阅当数据改变时,处理改变数据的函数
      this.lmStoreChange = this.lmStoreChange.bind(this);
      
    }

3.5.3 模块向 仓库管理员发送请求, 要求换批数据[ 利用 store.dispatch( 这里是ActionCreator.js种的 action 名称,注意加()执行一遍   );]
   3.5.3.1 利用store.dispatch 派发action ; 【这个action 会先到 ActionCreator.js 进行相应处理,然后再到 Reducer.js 中 对仓库,进行一个返回值的操作,从而让仓库的数据变化】
   3.5.3.2 利用store.subscribe(在模块中自定义一个函数);
   3.5.3.3 建议放在componentDidMount() 这个生命周期中进行异步请求;
   3.5.3.4 建议后面再添加一个生命周期函数 componentWillUnmount() 防止报错,后面第二份代码

    // 出了一个我也不是很理解的报错, 最后是这么解决的,就是加上了这句话,问题出在react中异步调用的情况
    // 我现在理解了这个错,已经渲染完了,却还有个异步回调没执行完, 需要改变state的值所以会出现这个情况
    componentWillUnmount = () => {
      this.setState = (state,callback)=>{
      return;
      };
    }
   
    // 回调函数,在store 的值变化时,对模块进行相应的操作
    lmStoreChange(){
      this.setState( store.getState() );
    }

就是;
//
    componentDidMount(){
// 派发action 告诉
      store.dispatch( funGetNewsList());

      // 最后一步订阅
      store.subscribe(this.lmStoreChange);
    }
   
至此,一个复杂的 redux 流结束;





页: [1]
查看完整版本: React 的 redux 重新学习[前面学废了]