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

Redux 简介-3

Redux 简介-3

清单 6 显示了 Stoplight 组件。
清单 6. 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
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { Component } from 'react';

const stopColor = (state) => {
  return state == 'STOP' ? 'red' : 'white';
}

const cautionColor = (state) => {
  return state == 'CAUTION' ? 'yellow' : 'white';
}

const goColor = (state) => {
  return state == 'GO' ? 'rgb(39,232,51)' : 'white';
}

export const Stoplight = ({
  store
}) => {
  const state = store.getState();

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

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

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

      </svg>
    </div>
  )
}




Stoplight 是一个 React 无状态功能组件,依据应用程序的状态来呈现不同颜色的 SVG 圆圈。该组件从存储的          getState() 方法获取状态,随后使用 3 个帮助器方法之一将状态转换为一种颜色。
通过调用  中 Redux 存储的 subscribe() 方法,React 在 Redux        状态更改时呈现交通信号灯。这些状态更改由应用程序的按钮发起。在清单 7 中(Buttons 组件的代码),可以看到按钮如何发起状态更改。
清单 7. 按钮          (buttons.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
26
27
28
29
30
31
import React, { Component } from 'react';
import { goAction, cautionAction, stopAction } from './actions';

export const Buttons = ({
  store
}) => {
  const state = store.getState();

  return(
    <div style={{textAlign: 'center'}}>
      <button onClick={() => {store.dispatch(goAction)}}
              disabled={state == 'GO' || state == 'CAUTION'}
              style={{cursor: 'pointer'}}>
        Go
      </button>

      <button onClick={() => {store.dispatch(cautionAction)}}
              disabled={state == 'CAUTION' || state == 'STOP'}
              style={{cursor: 'pointer'}}>
        Caution
      </button>

      <button onClick={() => {store.dispatch(stopAction)}}
              disabled={state == 'STOP' || state == 'GO'}
              style={{cursor: 'pointer'}}>
        Stop
      </button>
    </div>

  )
}




按钮被呈现时,它调用 Redux 存储的 getState() 方法来获取应用程序状态的引用。然后 Buttons        组件使用该状态配置按钮的已禁用状态。
当用户单击按钮时,该按钮的 onClick() 回调会调用 Redux 存储的 dispatch()        方法,并传递一个合适的操作。
无状态和相连组件示例应用程序通过注册一个回调来订阅 Redux 存储,只要存储状态发生更改,Redux 就会调用该回调。该回调呈现整个应用程序。实际上,用户会将整个应用程序连接到 Redux        存储。对于演示用途,连接整个应用程序已足够了,但最好通过 React 的 forceUpdate() 函数将 Redux 存储连接到单个组件。
清单 8 给出了交通信号灯应用程序的一个改良的入口点。
清单 8. 交通信号灯应用程序的改良后的入口点        (index.js)
1
2
3
4
5
6
7
8
9
10
11
'use strict';

import React from 'react';
import ReactDOM from 'react-dom';
import Redux, { createStore } from 'redux';

import { reducer } from './reducer';
import { App } from './app';

ReactDOM.render(<App store={createStore(reducer)}/>,
                document.getElementById('root'))




将清单 8 与  比较,可以看到代码不再在应用程序级别上订阅 Redux 存储。
清单 9 是一个实现 componentWillMount() 的经过改良的 Stoplight 组件。该方法会订阅 Redux        存储,在存储发生更改时调用该组件的 forceUpdate() 方法。
清单 9. 改良后的 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
'use strict';

import React, { Component } from 'react';

const stopColor = (store) => {
  return store.getState() == 'STOP' ? 'red' : 'white';
}

const cautionColor = (store) => {
  return store.getState() == 'CAUTION' ? 'yellow' : 'white';
}

const goColor = (store) => {
  return store.getState() == 'GO' ? 'rgb(39,232,51)' : 'white';
}

export class Stoplight extends Component {
  componentWillMount() {
    this.props.store.subscribe(() => {
      this.forceUpdate();
    });
  }

  render() {
    return(
      <div style={{textAlign: 'center'}}>
        <svg height='170'>
          <circle cx='145' cy='60' r='15'
                  fill={stopColor(this.props.store)}
                  stroke='black'/>

          <circle cx='145' cy='100' r='15'
                  fill={cautionColor(this.props.store)}
                  stroke='black'/>

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




清单 10 给出了一个改良后的 Buttons 组件,它经过了类似的改良,实现 componentWillMount() 来订阅        Redux 存储。
清单 10. 改良后的按钮          (buttons.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
26
27
28
29
30
31
32
33
34
35
36
37
38
'use strict';

import React, { Component } from 'react';
import { goAction, cautionAction, stopAction } from './actions';

export class Buttons extends Component {
  componentWillMount() {
    this.props.store.subscribe(() => {
      this.forceUpdate();
    });
  }

  render() {
    const state = this.props.store.getState();

    return(
      <div style={{textAlign: 'center'}}>
        <button onClick={() => {this.props.store.dispatch(goAction)}}
                disabled={state == 'GO' || state == 'CAUTION'}
                style={{cursor: 'pointer'}}>
          Go
        </button>

        <button onClick={() => {this.props.store.dispatch(cautionAction)}}
                disabled={state == 'CAUTION' || state == 'STOP'}
                style={{cursor: 'pointer'}}>
          Caution
        </button>

        <button onClick={() => {this.props.store.dispatch(stopAction)}}
                disabled={state == 'STOP' || state == 'GO'}
                style={{cursor: 'pointer'}}>
          Stop
        </button>
      </div>
    )
  }
}




将  中的 Stoplight 组件和         中的 Buttons 组件的实现与它们的原始实现比较一下( 和 )。可以看到,除了添加了 componentWillMount() 方法之外,两个组件都从无状态功能组件更改成了类。这是因为 React        无状态功能组件不支持 React 生命周期方法。
其他所有方面均类似,无状态组件最适合维护状态的组件,这也是 Redux 很有用的原因:维护状态容易出错,这是大部分 bug 的源头。在下一期文章中,将学习如何通过使用 Redux        React 绑定,将 Stoplight 和 Buttons 组件恢复为无状态组件。
返回列表