容器组件
一个容器组件主要负责维护状态和数据的计算,本身并没有界面逻辑,只把结果通过 props 传递下去。
区分容器组件的目的就是可以把组件的状态和渲染解耦开来,改写界面时可不用关注数据的实现,顺便得到了可复用性。
// bad
class MessageList extends Component {
constructor (props) {
super(props)
this.state = {
onlyUnread: false,
messages: []
}
}
componentDidMount () {
$.ajax({
url: "/api/messages",
}).then(({messages}) => this.setState({messages}))
}
handleClick = () => this.setState({onlyUnread: !this.state.onlyUnread})
render () {
return (
<div class="message">
<ul>
{
this.state.messages
.filter(msg => this.state.onlyUnread ? !msg.asRead : true)
.map(({content, author}) => {
return <li>{content}—{author}</li>
})
}
</ul>
<button onClick={this.handleClick}>toggle unread</button>
</div>
)
}
}
// good
class MessageContainer extends Component {
constructor (props) {
super(props)
this.state = {
onlyUnread: false,
messages: []
}
}
componentDidMount () {
$.ajax({
url: "/api/messages",
}).then(({messages}) => this.setState({messages}))
}
handleClick = () => this.setState({onlyUnread: !this.state.onlyUnread})
render () {
return <MessageList
messages={this.state.messages.filter(msg => this.state.onlyUnread ? !msg.asRead : true)}
toggleUnread={this.handleClick}
/>
}
}
function MessageList ({messages, toggleUnread}) {
return (
<div class="message">
<ul>
{
messages
.map(({content, author}) => {
return <li>{content}—{author}</li>
})
}
</ul>
<button onClick={toggleUnread}>toggle unread</button>
</div>
)
}
MessageList.propTypes = {
messages: propTypes.array.isRequired,
toggleUnread: propTypes.func.isRequired
}
更多阅读: