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

使用 Redux 实现异步操作-4

使用 Redux 实现异步操作-4

主题选择器组件清单 6 给出了主题选择器的容器组件的代码。
清单 6. 主题选择器容器          (containers/topicselector.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 TopicSelector from '../components/topicSelector';
import { setTopic } from '../actions';

const mapStateToProps = state => {
  return {
    topic: state.topic
  }
}

const mapDispatchToProps = dispatch => {
  return {
    setTopic: topic => {
      dispatch(setTopic(topic))
    }
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TopicSelector);




像所有 Redux 容器组件一样,TopicSelectorContainer        将状态和分派功能映射到关联的无状态组件的属性。在本例中,状态选择器容器映射一个主题和一个设置该主题的函数。
清单 7 显示了主题选择器无状态组件的代码。
清单 7. 主题选择器无状态组件          (components/topicselector.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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import React from 'react';

export const TopicSelector = React.createClass({
  propTypes: {
    topic: React.PropTypes.string.isRequired
  },

  componentDidMount: function() {
    function putCursorAtEnd(input) {
      const value = input.value;
      input.value = '';
      input.value = value;
    }

    let input = this.refs.input;

    input.focus();
    putCursorAtEnd(input);
  },

  handleChange: function(event) {
    this.props.setTopic(event.target.value);
  },

  handleKeyPress: function(event) {
    if(event.key == 'Enter') {
      this.props.setTopic(event.target.value);
    }
  },

  render: function() {
    const styles = {
      topic: {
        marginRight: '10px',
        fontFamily: 'tahoma',
        fontSize: '18px'
      },

      input: {
        fontFamily: 'tahoma',
        fontSize: '16px',
        marginRight: '10px'
      }
    };

    const topic = this.props.topic;

    return(
      <span>
        <span style={styles.topic}>
          Topic
        </span>

        <input type='text'
               ref='input'
               style={styles.input}
               defaultValue={topic}
               value={topic}
               onChange={this.handleChange}
               onKeyPress={this.handleKeyPress}/>
      </span>
    );
  }
})

TopicSelector.propTypes = {
  topic: React.PropTypes.string.isRequired,
  setTopic: React.PropTypes.func.isRequired,
  fetchTopic: React.PropTypes.func.isRequired,
};




主题选择器无状态组件包含一个提示和一个文本字段。当 React 挂载该组件时,该组件的 componentDidMount()        方法会提供文本字段的焦点,并将光标放在文本末尾。
当用户在文本字段中键入内容后按 Enter 时,该组件的 handleKeyPress() 方法会调用 setTopic()        方法。回想一下,该组件的属性中包含 setTopic() 方法,这是由于在该无状态组件的容器中调用了 connect()。
显示模式组件清单 8 给出了显示模式的容器组件。
清单 8. 显示模式容器          (containers/displayMode.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 DisplayMode from '../components/displayMode';
import { setDisplayMode } from '../actions';

const mapStateToProps = null;

const mapDispatchToProps = dispatch => {
  return {
    setListing: () => {
      dispatch(setDisplayMode('LISTING'))
    },

    setThumbnail: () => {
      dispatch(setDisplayMode('THUMBNAIL'))
    }
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(DisplayMode);




显示模式容器不会映射状态,但它会映射两个分派函数:setListing() 和        setThumbnail(),这两个函数会分派将应用程序的显示模式设置为列表或缩略图的操作。
清单 9 给出了显示模式无状态组件。
清单 9. 显示模式无状态组件          (components/displayMode.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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import React from 'react';

require('./book.css');

const DisplayMode = ({
  setListing,
  setThumbnail,
  displayMode
}) => {
  const switchToListing = function(event) {
    setListing();
  };

  const switchToThumbnail = function(event) {
    setThumbnail();
  };

  const styles = {
    radio: {
      marginLeft: '10px',
      cursor: 'pointer'
    },

    radiospan: {
      marginLeft: '20px',
      fontFamily: 'tahoma',
      fontSize: '16px'
    }
  };

  return(
    <span>
      <span style={styles.radiospan}>
        Thumbnail
      </span>

      <input type='radio'
             name='display'
             style={styles.radio}
             onChange={switchToThumbnail}
             checked={displayMode == 'THUMBNAIL'}
             value='thumbnail'/>

      <span style={styles.radiospan}>
        List
      </span>

      <input type='radio'
             name='display'
             style={styles.radio}
             onChange={switchToListing}
             checked={displayMode != 'THUMBNAIL'}
             value='list'/>
    </span>
  );
};

DisplayMode.propTypes = {
  setListing: React.PropTypes.func.isRequired,
  setThumbnail: React.PropTypes.func.isRequired,
  displayMode: React.PropTypes.string.isRequired
};

export default DisplayMode;




清单 9 中的无状态组件访问 3 个属性:setListing()、setThumbnail() 和          displayMode。显示模式容器传递 setListing()、setThumbnail()        属性。在  中可以看到,displayMode 属性由 Controls        无状态组件设置。
图书搜索应用程序当前的初始实现演示了组合缩减程序和实现操作创建器的过程。接下来,您将看到如何通过 Redux 和 React 实现异步操作。
返回列表