容器组件

一个容器组件主要负责维护状态和数据的计算,本身并没有界面逻辑,只把结果通过 props 传递下去。

区分容器组件的目的就是可以把组件的状态和渲染解耦开来,改写界面时可不用关注数据的实现,顺便得到了可复用性。

  1. // bad
  2. class MessageList extends Component {
  3. constructor (props) {
  4. super(props)
  5. this.state = {
  6. onlyUnread: false,
  7. messages: []
  8. }
  9. }
  10. componentDidMount () {
  11. $.ajax({
  12. url: "/api/messages",
  13. }).then(({messages}) => this.setState({messages}))
  14. }
  15. handleClick = () => this.setState({onlyUnread: !this.state.onlyUnread})
  16. render () {
  17. return (
  18. <div class="message">
  19. <ul>
  20. {
  21. this.state.messages
  22. .filter(msg => this.state.onlyUnread ? !msg.asRead : true)
  23. .map(({content, author}) => {
  24. return <li>{content}—{author}</li>
  25. })
  26. }
  27. </ul>
  28. <button onClick={this.handleClick}>toggle unread</button>
  29. </div>
  30. )
  31. }
  32. }
  1. // good
  2. class MessageContainer extends Component {
  3. constructor (props) {
  4. super(props)
  5. this.state = {
  6. onlyUnread: false,
  7. messages: []
  8. }
  9. }
  10. componentDidMount () {
  11. $.ajax({
  12. url: "/api/messages",
  13. }).then(({messages}) => this.setState({messages}))
  14. }
  15. handleClick = () => this.setState({onlyUnread: !this.state.onlyUnread})
  16. render () {
  17. return <MessageList
  18. messages={this.state.messages.filter(msg => this.state.onlyUnread ? !msg.asRead : true)}
  19. toggleUnread={this.handleClick}
  20. />
  21. }
  22. }
  23. function MessageList ({messages, toggleUnread}) {
  24. return (
  25. <div class="message">
  26. <ul>
  27. {
  28. messages
  29. .map(({content, author}) => {
  30. return <li>{content}—{author}</li>
  31. })
  32. }
  33. </ul>
  34. <button onClick={toggleUnread}>toggle unread</button>
  35. </div>
  36. )
  37. }
  38. MessageList.propTypes = {
  39. messages: propTypes.array.isRequired,
  40. toggleUnread: propTypes.func.isRequired
  41. }

更多阅读: