一.包含父子组件的Tab切换
当我们将tab切换分离到子组件时很多人喜欢这样写
父组件:
class App extends Component{
constructor(props){
super(props);
this.state = {
};
this.type = 0;
}
tabSwitch(){
this.setState({
//change state
})
}
render(){
return (
<Tab renderFun={this.tabSwitch} type={this.type} />
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
子组件:
export default class Tab extends Component{
constructor(props){
super(props);
this.state = {
tab:['tab1','tab2'],
current:this.props.type
};
}
tabSwitch(index){
this.setState({
current:index
},() => {
this.props.renderFun(this.state.current);
})
}
render(){
var _this = this;
return (
<div className='tab'>
{ this.state.tab.map(function(ele,index){
return <div key={index} className={'tab_' + index + ' ' + (_this.state.current == index ? 'tab_active':'')} onClick={_this.tabSwitch.bind(_this,index)}>{ele}</div>
})
}
</div>
)
}
}
这样的写法实现功能是没问题。当我们切换tab时,将点击的tab栏目传递给父组件,父组件改变state去重新渲染tab列表。但是这里虽然功能实现,但是这样会有重复渲染的问题出现。
组件更新过程:shouldComponentUpdate=》componentWillUpdate-》render-》componentDidUpdate
我们在子组件点击的时候,setState改变了current,子组件重新渲染,然后回调点击的tab给父组件,父组件执行setState会开始更新过程,这时候父组件的shouldComponentUpdate未设置,默认是true,父组件完成了更新过程,由于父组件的渲染,所以子组件也开始更新过程,此时shouldComponentUpdate也是true,子组件也会完成更新过程。子组件相当于重复渲染了一次
正确的写法:
React建议将关系到渲染的数据保存在state中。这里能勾关系到渲染的就是这个type了。因为type的改变会导致我们的列表改变
父组件:
class App extends Component{
constructor(props){
super(props);
this.state = {
type:0
};
}
tabSwitch(index){
this.setState({
type:index
})
}
render(){
return (
<Tab renderFun={this.tabSwitch} type={this.state.type} />
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
子组件:
export default class Tab extends Component{
constructor(props){
super(props);
this.state = {
tab:['tab1','tab2'],
};
this.current = this.props.type;
}
shouldComponentUpdate(newProps, newState) {
return newProps.type !== this.props.type; //此时返回false,子组件不会被重复渲染
}
tabSwitch(index){
this.current = index;
this.props.renderFun(index);
}
render(){
var _this = this;
return (
<div className='tab'>
{ this.state.tab.map(function(ele,index){
return <div key={index} className={'tab_' + index + ' ' + (_this.current == index ? 'tab_active':'')} onClick={_this.tabSwitch.bind(_this,index)}>{ele}</div>
})
}
</div>
)
}
}
网友评论