首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

结合使用 Redux 和 React-1

结合使用 Redux 和 React-1

使用 react-redux 绑定GitHub 上提供了针对多个流行框架的 Redux 绑定,包括 React、Angular 和 Vue。这些绑定使得将 Redux 与通过这些框架构建的应用程序相集成变得很容易。
Redux 中不包含 react-redux 绑定,所以您必须使用以下命令单独安装它们:npm install react-redux

绑定提供了一个 API,该 API 包含一个        React 组件和一个 JavaScript 方法:
  • Provider 组件允许 Provider 组件中包含的组件访问 Redux 存储。
  • void connect([mapStateToProps], [mapDispatchToProps], [mergeProps],            [options]) 函数将一个 React 表示组件连接到 Redux 存储。
Provider 组件很方便,您不需要在整个组件分层结构中手动传递存储作为一个属性。嵌套在 Provider        组件内的组件会自动获得 Redux 存储的访问权。
connect() 函数将一个表示组件连接到 Redux 存储,以便在存储更改时更新该组件。
与 Redux 存储的自动连接在  中,了解了如何将单个 React 组件连接到 Redux 存储。这种风格非常流行,以至于 redux-react 绑定提供了一个          connect() 方法来自动将无状态功能组件连接到存储。
在本文的整篇文章中,stoplight 都与交通信号灯 同义。

为了演示,我首先将修改  的交通信号灯应用程序的 App 组件,让其使用称为容器组件 的组件 — 这类组件会自动连接到        Redux 存储,并向一个封闭的无状态功能组件提供属性。清单 1 给出了更新后的 App 组件。
清单 1. 应用程序          (app.js),其中现在使用了容器组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React, { Component } from 'react';
import { StoplightContainer } from './stoplight-container';
import { ButtonContainer } from './button-container';
import { createStore } from 'redux';
import { reducer } from './reducer';

export class App extends Component {
  render() {
    const store = createStore(reducer);

    return(
      <div>
        <StoplightContainer store={store}/>
        <ButtonContainer store={store}/>
      </div>
    )
  }
}




没有像原始实现中一样返回包含 Stoplight 和 Buttons 组件的          DIV,App 组件的经过改良的 render() 方法返回了一个包含两个容器组件的          DIV:StoplightContainer 和 ButtonContainer。
请注意,我仍将 Redux 存储传递给了 App 组件中包含的组件。您会在下一节看到如何规避该需求。
清单 2 显示了 stoplight 容器。
清单 2. stoplight 容器          (stoplight-container.js)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { connect } from 'react-redux';
import { Stoplight } from './stoplight';

const mapStateToProps = state => {
  return {
    goColor:      state == 'GO'      ? 'rgb(39,232,51)' : 'white',
    cautionColor: state == 'CAUTION' ? 'yellow' : 'white',
    stopColor:    state == 'STOP'    ? 'red' : 'white'
  }
}

const mapDispatchToProps = null;

export const StoplightContainer = connect(
    mapStateToProps,
    mapDispatchToProps
)(Stoplight);




简单来讲,StoplightContainer 连接到 Redux 存储,并将应用程序状态映射到它包含的 stoplight 的属性。应用程序状态为          GO、CAUTION 或 STOP,stoplight 的属性为          goColor、cautionColor 和 stopColor。
默认情况下,stoplight 的 3 个属性中的每一个都是 white。当状态为 GO 时,stoplight 容器会将        stoplight 的 goColor 属性映射到绿灯(编码为 rgb(39,232,51))。当状态为          CAUTION 时,会将 cautionColor 映射到 yellow。当状态为 STOP,会将        stopColor 映射到 red。
为了将应用程序状态映射到 stoplight 属性, 使用了 react-redux 绑定的          connect() 函数将 StoplightContainer 连接到 Redux 存储。
通过调用 connect() 函数并将 Stoplight 传递给 connect()        返回的函数,Redux 在 Redux 存储中的状态发生更改时自动更新 Stoplight。您只需调用 connect()        即可实现此目的。当存储发生更改时,Redux 会调用 StoplightContainer 的 mapStateToProps()        方法。Redux 将 StoplightContainer.mapStateToProps() 返回的对象的属性值复制到          StoplightContainer 中包含的 stoplight。
connect() 方法接受两个参数,这两个参数都是函数。第一个函数将来自 Redux 存储的状态映射到所包含的组件(在本例中为          Stoplight)的属性。第二个函数将 Redux 分派调用映射到属性;但是,stoplight 不启用任何行为,所以 stoplight        容器不会将分派调用映射到属性。结果,stoplight 容器的 mapDispatchToProps 函数为 null。
清单 3 显示了 Stoplight 组件的经过再次改良的实现,其中使用了它的 3 个属性作为 SVG 圆圈的 fill        属性。
清单 3. Stoplight        (stoplight.js),已恢复为无状态功能组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import React, { Component } from 'react';

export const Stoplight = ({
  goColor,
  cautionColor,
  stopColor
}) => {
  return(
    <div style={{textAlign: 'center'}}>
      <svg height='170'>
        <circle cx='145' cy='60' r='15'
                fill={stopColor}
                stroke='black'/>

        <circle cx='145' cy='100' r='15'
                fill={cautionColor}
                stroke='black'/>

        <circle cx='145' cy='140' r='15'
                fill={goColor}
                stroke='black'/>
      </svg>
    </div>
  )
}




Stoplight 组件已恢复为无状态功能组件,它从 StoplightContainer 组件接收自己的属性。
清单 4 显示了 ButtonContainer 组件。
清单 4. 按钮容器          (button-container.js)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { connect } from 'react-redux';
import { Buttons } from './buttons';
import { goAction, cautionAction, stopAction } from './actions';

const mapStateToProps = state => {
  return {
    lightStatus: state
  }
}

const mapDispatchToProps = dispatch => {
  return {
    go:      () => { dispatch(goAction) },
    caution: () => { dispatch(cautionAction) },
    stop:    () => { dispatch(stopAction) }
  }
}

export const ButtonContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(Buttons);




ButtonContainer 组件将当前状态映射到一个名为 lightStatus 的 Buttons          属性。信号灯状态就是状态的值(GO、CAUTION 或 STOP)。
返回列表