|
本帖最后由 周大胖子 于 2020-11-25 16:31 编辑
加深理解:
react是 ui 层的框架 ,不适合开发大型项目,为此有了 redux 这个数据层的框架 ;
redux = Reducer + Flux[这个是最原始层的react数据层框架] ;
问我为啥要知道这个:我怕哪天HR装逼的问我,我好回答他。
开始理使用模式: 一、安装篇:
1. 安装 redux
cnpm install --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 流结束;
|
|