REACT Redux 入门

Redux 入门

Redux 工作流程

redux是视图层框架,把所有数据都放在store之中,每个组件都要从store里拿数据,然后每个组件也能去改store里面的数据,
举例:把这个流程理解成一个图书馆的流程

  1. react compontents:借书的人

  2. action creators:“要借什么书”这句话(语句的表达,数据的传递)

  3. store:图书馆管理员(没办法记住所有书籍的存储情况)

  4. reducers:图书馆管理员的记录本(要借什么书,先查有没有,要还的书查一下放到某个位置);

    借书的人
    ——我要借一本书
    ——图书管理员听见
    ——查阅reducers手册
    ——去store找书
    ——把对应的书给借书人;

请添加图片描述

创建 store 和 reducers
// store
// ./store/index.js

import { createStore } from 'redux';
import reducer from './reducer'

const store = createStore(reducer);

export default store;

// ./store/reducer.js
const defaultState = { // 数据
    inputValue: '123',
    list: [
        'Racing car sprays burning fuel into crowd.',
        'Japanese princess to wed commoner.',
        'Australian walks 100km after outback crash.',
        'Man charged over missing wedding girl.',
        'Los Angeles battles huge wildfires.',
    ]
}

// $$$ reducer 可以接收state 但是绝不能直接修改state $$$
export default (state = defaultState, action) => {
    return state;
}

// index.js
import store from './store/index'
this.state = store.getState(); // 使用数据



Acition 和 Reducer 的编写
  1. 要想更新state中的数据,首先派发一个action,action通过dispatch方法传给store。
  2. store把之前的数据previousState和传过来的action自动转发给reducers函数。
  3. reducers接收state和action后进行数据处理,重新生成一个newState(原state只读不改),把newState作为返回值返回给store。
  4. store接收newState,将新数据替换原来的数据。
  5. react组件中观测到数据发生改变(store.subscribe),会从store里面重新取数据(state),更新组件的内容,页面发生变化。
ActionTypes 的拆分
// actiontypes.js 
export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';

优点:好处是变量写错会报错 易于代码书写

action 的统一管理 actionCreator
// actionCreator.js

import { CHANGE_INPUT_VALUE, ADD_TODO_ITEM, DELETE_TODO_ITEM } from './actionTypes';

export const getInputChangeAction = (value) => ({
	type: CHANGE_INPUT_VALUE,
	value
});

export const getAddItemAction = () => ({
	type: ADD_TODO_ITEM
});

export const getDeleteItemAction = (index) => ({
	type: DELETE_TODO_ITEM,
	index
});

优点:把action都集中写在一个文件中,方便后期维护和自动化测试

Redux 总结
redux三个基本原则:

①:store必须是唯一的
②:只有store可以改变自己的内容
③:reducer 必须是纯函数

只有store能改变自己内容说明在reducer里我们不能直接操作state,只能通过定义新变量copy state的值,然后对新变量进行操作并 return 出新变量,不允许直接改变state。
什么是纯函数?
给固定的输入,就一定会有固定的输出,并且不会有任何副作用。
所以对于异步函数(定时器、ajax数据请求等)、动态时间都不适意在reducer里订阅。

store核心api:
  • crerteStore(): 创建一个store
  • store.dispatch(action): 派发action,传递store
  • store.getState(): 获取store的所有数据
  • store.subscribe(): 订阅store的变化,接收的回调函数在store改变时候就会自动执行

Redux 进阶

什么是 Redux 的中间件?

中间件:在action和store中间,对store的dispath方法的升级;
例如thunk中间件,使得dispath可以接受函数,如果传递过来的action是一个函数那么就先执行,如果传递过来的action是一个对象(action只能是一个对象,当使用了redux-thunk后,action可以是一个函数),那就直接传给reducers

  • redux-thunk 把异步操作都放在action中
  • redux-saga 把异步操作放在单独文件中
    请添加图片描述
使用Redux-thunk 中间件实现ajax数据请求
  1. 不使用中间件,store接收的action只能是对象;有了中间件(redux-thunk),action可以是一个函数,通过store.dispatch这个方法将action函数传给store。
  2. store接收到action之后发现action是函数而不是对象,则会执行调用这个action函数。
  3. action函数内部先进行异步请求获取数据,之后去改变store中的数据(state)。
  4. 首先内部创建一个action对象,外部action这个函数默认接收store的dispatch方法,因此直接调用dispatch方法将内部action对象传给store,store便可以更新数据。
// index.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
  applyMiddleware(thunk),
);

const store = createStore(reducer, enhancer);

export default store;

// TodoList.js
 componentDidMount() {
   const action = getTodoList();
	store.dispatch(action);
 }

// actionTypes.js
export const INIT_LIST_ACTION = 'get_init_action';

// actionCreators.js
import { INIT_LIST_ACTION } from './actionTypes';
import axios from 'axios';

export const initListAction = (data) => ({
	type: INIT_LIST_ACTION,
	data
});

export const getTodoList = () => {
	return (dispatch) => {
		axios.get('/list.json').then((res)=>{
			const data = res.data;
			const action = initListAction(data);
			dispatch(action);
		  })
	}
}
Redux-saga 中间件入门
// index.js
import { createStore, applyMiddleware, compose } from 'redux';
import reducer from './reducer';
import mySaga from './sagas';
import createSagaMiddleware from 'redux-saga';

const sagaMiddleware = createSagaMiddleware();

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
  applyMiddleware(sagaMiddleware)
);

const store = createStore(reducer, enhancer);
sagaMiddleware.run(mySaga);

export default store;

// sagas.js
import { takeEvery, put } from 'redux-saga/effects';
import { GET_INIT_LIST } from './actionTypes';
import { initListAction } from './actionCreators';
import axios from 'axios';

function* getInitList() {
    const res = yield axios.get('/list.json');

    const action = initListAction(res.data);

    yield put(action);
}
// generator 函数
function* mySaga() {
    yield takeEvery(GET_INIT_LIST, getInitList);
}

export default mySaga;

// actionTypes.js
export const GET_INIT_LIST = 'get_init_list';

// actionCreators.js
import { GET_INIT_LIST } from './actionTypes';

export const getInitList = () => ({
	type: GET_INIT_LIST
});


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值