其实你会发现redux并没那么难!

Redux特色

  • 统一的状态管理,一个应用中只有一个仓库(store)
  • 仓库中管理了一个状态树(statetree)
  • 仓库不能直接修改,修改只能经过派发器(dispatch)派发一个动做(action)
  • 更新state的逻辑封装到reducer中,reducer是纯函数

Redux流程图

Rdeux中重要对象说明

store

是一个数据仓库,一个应用中store是惟一的,它里面封装了state状态,当用户想访问state的时候,只能经过store.getState来取得state对象。css

action

action描述了一个更新state的动做,它是一个对象,其中type属性是必须有的,reducer会根据type来指定某动做和要修改的值。react

{
    type: FETCH_POSTS,
    payload: posts  // 数据源
}
复制代码

dispatch

dispatch是一个方法,它用于派发一个action,这是惟一的可以修改state的方法。git

fetch("https://jsonplaceholder.typicode.com/posts")
    .then(
        posts => dispatch({
            type: FETCH_POSTS,
            payload: posts
        })   
    )
复制代码

reducer

reducer是更新state的核心,它里面已经封装好了更新state的逻辑,接受两个参数,state和action,将新值更新到旧的state对象上返回。github

// 根据action的type,返回不一样数据

switch (action.type) {
    case FETCH_POSTS:
        return {
            ...state,
            items: action.payload
        };
    default:
        return state;
}
复制代码

React中使用Redux

项目目录结构

屏幕快照 2019-09-02 下午2.54.02.pngjson

入口文件index.js

import { Provider } from 'react-redux';
import { store } from './redux/store';

// Provider包裹以后,全部的组件均可以拿到store库中数据
<Provider store={store}>
    // 项目中经常使用Provider包裹最底层父组件,以保证全部组件都能共享数据
    <Index />
</Provider>
复制代码

数据仓库store.js

  1. 引入所需文件和插件
import {applyMiddleware, createStore} from "redux";
import rootReducer from './reducers/index.js';
import thunk from 'redux-thunk'; // thunk做用是异步的分发action

const middleware = [thunk]; // 中间件
const initialState = {};
复制代码
  1. 经过createStore方法建立库,接受三个参数(reducer,state,中间件)
// applyMiddleware将全部中间件组成一个数组并依次执行
export const store = createStore(
    rootReducer,
    initialState,
    applyMiddleware(...middleware),
);
复制代码

actions/postAction.js

// 分发操做
export const fetchPosts = () => dispatch => {
    fetch("https://jsonplaceholder.typicode.com/posts")
        .then(res => res.json())
        .then(posts => dispatch({
            type: 'FETCH_POSTS', // type是必需要有的
            payload: posts // 有效数据
        }));
};
复制代码

reducers/postReducer.js

const initialState = {
    items: [],
    item: {}
};

// reducer接受两个参数,第一个是state,第二个是action
export default function (state = initialState, action) {
    switch (action.type) {
        case FETCH_POSTS:
            return {
                ...state,
                items: action.payload
            };
        default:
            return state;
    }
}
复制代码

组件触发action

  1. 以components中的Posts组件来讲明,引入所需数据和方法
import {connect} from 'react-redux';
import {fetchPosts} from "../redux/actions/postActions";

@connect(state => {
    let {items, item} = state.posts;
    return {
        items,
        item
    }
},{fetchPosts})
复制代码
  1. 经过this.props引入
componentDidMount () {
    this.props.fetchPosts();
}

componentWillReceiveProps (nextProps) {
    if(nextProps.item){
        this.props.items.unshift(nextProps.item);
    }
}
复制代码

项目完整代码

github.com/GaoHeming11…redux

补充

引入第三方库antd时按需加载

yarn add babel-plugin-import --save

// 在package.json中添加
"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      [
        "import",
        {
          "libraryName": "antd",
          "style": "css"
        }
      ]
    ]
}
复制代码

connect装饰器写法

  1. 未用装饰器写法
// 将最新的state映射到当前组件,经过mapStateToProps订阅store
const mapStateToProps = state => ({
    posts: state.posts.items,
});

// 将当前组件Posts和action进行连接
// connect接受两个参数,第二个参数里面能够包含多个方法
export default connect(mapStateToProps,{fetchPosts})(Posts)
复制代码
  1. 使用装饰器写法
yarn add babel-plugin-transform-decorators-legacy

// 可省略如上步骤,在头部引入所需state和action,而后直接导出组件
@connect(state => {
    let {
        items,
        item
    } = state.posts;
    return {
        items,
        item
    }
},{fetchPosts}),

export default Posts;
复制代码

刚刚加入掘金社区,欢迎提出宝贵的意见,一块儿进步学习。数组

相关文章
相关标签/搜索