Redux 和 React-Redux 基本使用

446 阅读5分钟

刚开始接触 React 时就听过 Redux ,虽然 ReduxReact 并不是必要的,但在 React 生态中也是个使用比较频繁的组件,相信也值得花时间好好了解。

在使用后,也能感受到 Redux 对项目带来的好处:

  1. 让组件管理 state 更方便,且确保整个项目的数据都来自同一个地方。
  2. 开发时能让界面及数据端分离,有关界面的就修改 React 的 component,数据的部分就完全交给 Redux,每个人各司其职、分工合作。

既然 ReactRedux 两者间可以这么相处融洽,那不如就开始试试吧!

Redux 基本用法

在讲解两者如何配合前,还是得先了解 Redux 的运作模式。

创建 Reducer

ReducerRedux 中是用来保管 state ,以及在接收到不同的 action 指令时该对 state 做什么动作的函数。

首先要为该 Reducer 设计它所管理的 state 结构:

const initState = {
    name: 'Jack',
}

虽然在 Reducer 中也可以改变 state 的结构,但在 initState 中将数据结构清楚列出,还能让接手的人或是两个礼拜后的自己,一看就能知道这个 Reducer 保管了哪些数据。

现在有了初始数据,就可以使用它建立一个 Reducer

const reducer = (state = initState, action) => {
    switch (action.type){
        default:
            return state
    }
}

每一个 Reducer 都会有两个参数,第一个参数会将初始的数据状态 initState 交由 Reducer 保管,第二个参数会传入现在 reducer 要对 state 做什么动作的指令及额外的参数,这些在后几篇会再讲解,所以在还没有任何 action 指令描述的 Reducer 内,默认返回了它所保管的 state ,在这里就是上方的 initState

创建 store

创建 Reducer 后,还得将它交由 storestore 的工作就是在应用程序中负责整合所有的 Reducer

创建前,得先从 reduximport 进负责创建 store 的函数 createStore ,并将 Reducer 传入以创建一个 store

import { createStore } from 'redux'

const store = createStore(reducer)

//可使用 store 的内置函数 getState() 确认目前 store 内所保管的数据console.log(store.getState())  // {name: 'Jack'}

需要注意的是,每个项目都应该只能有一个 store 存在,若是有许多不同类型的数据,则是以 Reducer 区分,最后将多个 Reducer 打包成一个后,再创建 store ,这部分的使用方法,在日后的文章也会解说。

store 产生后, Redux 的前置准备部分就告一段落,接下来说明 Reactcomponent 该如何从 Reduxstore 中取到数据。

React-Redux 登场

React-Redux的架构中,我们需要一种方法来告诉React组件它应该从Redux store中获取哪些数据。这就像是在超市购物时,你会有一个购物清单,上面列出了你需要购买的所有商品。在这个比喻中,数据映射函数就相当于你的购物清单。

  1. 创建购物清单:首先,你需要创建一个购物清单,这个清单是一个函数,它定义了你需要从Redux store中获取哪些数据项。在这个函数中,你会指定每项数据的名称和它在store中的位置。
  2. 连接超市和购物车:然后,你将这个购物清单与超市(Redux store)和购物车(React组件)连接起来。这样,当你需要数据时,可以根据购物清单上的信息,从store中取出对应的数据。
  3. 填充购物车:最后,通过一个连接器(React-Reduxconnect函数),将购物清单上的数据项填充到购物车中,这样你的组件就可以使用这些数据来渲染界面了。

React 需通过几个步骤才能将 Redux 所保管的数据流向 component 。首先需要定义要从 store 中取得的数据,并将 component 与该数据源连接起来,之后再利用 Providerstore 根据组件中使用到的参数将对应数据流进 component 中。以下开始实现这些步骤:

定义数据

const mapStateToProps = state => ({
    name: state.name
})

上方创建一个函数 mapStateToProps ,并在该函数内部定义需要哪些数据,它有个参数 state ,在连接时 Redux 会将 store 传进这个位置,因此上方指定了 store 中保管的 name 数据,并以 namekeyprops 流进 component 中。

创建组件

import React from 'react'

class ConnectTitle extends React.Component {
    render(){
        return <h1>Hello!{this.props.name}</h1>
    }
}

因为待会会与 mapStateToProp 进行连接,所以在组件名称前个人多注记了 Connect ,代表该 component 内含有从 store 中取的数据,而上方的 {this.props.name} 正是数据定义时指定的名称也就是 name

连接 componentmapStateToProps

在这个步骤前得先从 react-reduximportconnect ,再进行连接:

import { connect } from 'react-redux'

const Title = connect(mapStateToProps)(ConnectTitle)

通过 connect 分别将 mapStateToPropsConnectTitle 送进处理,会得到一个新的 component ,在上方使用 Title 接收结果。

设置 Provider

Providerreact-redux 中的组件,它会接收上方在 Redux 中创建的 store ,并根据和 component 绑在一起的mapStateToProps 上要求的数据从 store 中取出,再通过 props 流向 component

import { connect, Provider } from 'react-redux'
import ReactDOM from 'react-dom'

ReactDOM.render(<Provider store={store}>
                    <Title />
                </Provider>,
                document.getElementById('root'))

上方的 Provider 在最外层,并为他指定了 store

注意!不论是多么大的项目, Provider 永远都在最外层,也永远都只有一个,为了保持数据来源都是从 Provider 流进内部的 component ,这也是为什么每个项目中 store 应该都只能有一个。

接着运行应用程序,确认最后输出的结果:

本文是关于ReactRedux最基本使用方式,笔者刚学的时候真的觉得很困难,也有许多观念一直理不清楚,包括上面提到的store为什么只能有一个,不过好在三番两次的实际操作后,不仅更了解,而且像开头说的,体会到使用Redux的好处后,对他就更爱不释手,希望本篇文章能够带给和当初的我一样,为学习Redux困扰的大家。