redux实际使用细节点

347 阅读3分钟

上一节我们学习了最基本的redux概念,但是这时会有一个问题,在实际的开发中我们要怎么使用呢?学习的终极目标是使用,光学不用假功夫, 我们这次就来看看redux和react实际项目的结合。

文件结构

通过上节的学习,我们知道redux有三大基本概念,action、reducers 、store缺一不可,那么怎样组织代码结构也就显而易见了, 我们在项目中创建一个单独的redux文件夹,其中包含action、reducers 、store:

img.png

sagas是之后学习到中间件时的知识,此处可以暂时不管,那你可能要问了,这里只看到了actions和reducers,store在哪里呢?

Store

其实他就是index.js,在该文件中我们只需要将reducers引入并放在createStore的第一个参数即可:

import {createStore} from "redux";
import reducers from "./reducers";

let store;

store = createStore(reducers);

export default store;

这样我们的store就创建好了。真正的store定义其实在每个reducers中就定义好了。

注意这里我们只是使用了最基本的方式去进行了创建,之后当引入中间件时我们还会对创建过程进行进一步的深化。

创建出store后就需要将store整个挂载在app上,这样你的整个app才能访问到Redux store中的数据:

import React from "react";
import ReactDOM from "react-dom";

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

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

Action

我们在具体的页面上可以使用react-redux提供的connect()帮助起来调用。 bindActionCreators() 可以自动把多个 action 创建函数 绑定到 dispatch() 方法上。

我们先来看一下connect方法,它接收两个参数,都是可选的:

  • mapStateToProps:每当store state发生变化时,就被调用。接收整个store state,并且返回一个该组件所需要的数据对象
  • mapDispatchToProps:这个参数可以是一个函数或对象
    • 如果是一个函数,一旦该组件被创建,就会被调用。接收dispatch作为一个参数,并且返回一个能够使用dispatch来分发actions的若干函数组成的对象*
    • 如果是一个action creators构成的对象,每一个action creator将会转化为一个prop function并会在调用时自动分发actions。注意: 我们建议使用这种形式。

通常我们可以这样去connect

@connect(
    state => ({}),
    dispatch => ({})
)
export default class App extends Component {
   // ...
}

其中第一个参数中就可以写我们在这个页面中需要用到的所有store中数据,而第二个参数中就可以写我们这个页面中所有会被发起的actions。

@connect(
    state => ({
        num: state.numReducers.num // reducer中定义的state
    }),
    dispatch => ({
        addNum: bindActioCreators(addNum,dispatch) // 创建出一个可以直接在页面中调用的dispatch(action)
    })
)

这里的addNum就是我们需要在action中去定义的action创建函数。

// num加
export const addNum = (payload) => {
    return {
        type: 'num add',
        payload
    }
};

注意一般在大型的项目中因为actions会有很多,所以我们会将type的定义单独的放在一个actionType.js文件夹中,统一进行创建,这样方便后期维护。

Reducers

Reducers在项目中使用和基础的没有什么不同,需要在其中定义initState和一个纯函数对state和action进行计算,返回一个新的state。

需要注意的就是随我们的应用体积变大,我们应该将不同功能模块的reducers进行拆分提取,每个模块有自己的reducer,最后通过redux提供的 combineReducers()工具类将他们整合起来,将生成的对象放入store的createStore()中即可。