組件和組件容器
我們可以通過一個例子來說明組件和組件容器的作用,比如下面的始終的例子。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { time: this.props.time };
this._update = this._updateTime.bind(this);
}
render() {
const time = this._formatTime(this.state.time);
return (
<h1>
{ time.hours } : { time.minutes } : { time.seconds }
</h1>
);
}
componentDidMount() {
this._interval = setInterval(this._update, 1000);
}
componentWillUnmount() {
clearInterval(this._interval);
}
_formatTime(time) {
var [ hours, minutes, seconds ] = [
time.getHours(),
time.getMinutes(),
time.getSeconds()
].map(num => num < 10 ? '0' + num : num);
return { hours, minutes, seconds };
}
_updateTime() {
this.setState({
time: new Date(this.state.time.getTime() + 1000)
});
}
};
ReactDOM.render(<Clock time={ new Date() }/>, ...);
我們可以看到click這個組件擔任的責任有點多,view層以及數據處理邏輯等都是在這里面進行處理的,其中數據和view都不能被其他組件共享。
提取組件
組件應該是由純函數構造而成的,它內部不應該有狀態。
// Clock/Clock.jsx
export default function Clock(props) {
var [ hours, minutes, seconds ] = [
props.hours,
props.minutes,
props.seconds
].map(num => num < 10 ? '0' + num : num);
return <h1>{ hours } : { minutes } : { seconds }</h1>;
};
提取容器
容器應該是各個組件進行組合和數據處理的地方。
// Clock/index.js
import Clock from './Clock.jsx'; // <-- that's the presentational component
export default class ClockContainer extends React.Component {
constructor(props) {
super(props);
this.state = { time: props.time };
this._update = this._updateTime.bind(this);
}
render() {
return <Clock { ...this._extract(this.state.time) }/>;
}
componentDidMount() {
this._interval = setInterval(this._update, 1000);
}
componentWillUnmount() {
clearInterval(this._interval);
}
_extract(time) {
return {
hours: time.getHours(),
minutes: time.getMinutes(),
seconds: time.getSeconds()
};
}
_updateTime() {
this.setState({
time: new Date(this.state.time.getTime() + 1000)
});
}
};
優點
職責的劃分更加明顯:容器不需要了解圖形的繪制,組件不需要了解數據的處理。
重用性更高:由于組件只是用來顯示數據沒有太多的業務邏輯,就能很好的被拿來重用