React学习之进阶终临高阶组件(二十一)
准确地来说, const EnhancedComponent = higherOrderComponent(WrappedComponent);
就是说,
接下来,将讨论的是 1.构造联系之前我提到的 组件是 如下: class CommentList extends React.Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this);
this.state = {
// "DataSource"是一个全局的数据处理类,用来处理数据的,可以不要在意其中的细节
comments: DataSource.getComments()
};
}
componentDidMount() {
//监听数据变化
DataSource.addChangeListener(this.handleChange);
}
componentWillUnmount() {
// 清除监听事件
DataSource.removeChangeListener(this.handleChange);
}
handleChange() {
// 当数据发生变化时触发事件
this.setState({
comments: DataSource.getComments()
});
}
render() {
return (
<div>
{this.state.comments.map((comment) => (
<Comment comment={comment} key={comment.id} />
))}
</div>
);
}
}
这其中的DataSource用到了观察者模式,在组件中进行事件的订阅。我们再看下面这份代码 class BlogPost extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
blogPost: DataSource.getBlogPost(props.id)
};
}
componentDidMount() {
DataSource.addChangeListener(this.handleChange);
}
componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}
handleChange() {
this.setState({
blogPost: DataSource.getBlogPost(this.props.id)
});
}
render() {
return <TextBlock text={this.state.blogPost} />;
}
}
两份代码相似但是有不同,他们最终渲染出的结果是不同的,但是有三点是相同的
可以想象的是,当我们构建大型的应用程序的时候,通过订阅 我们可以写一个创建组件的函数,像CommentList和blogPost那样去订阅DataSource。这个函数接受一个组件作为参数来监听事件。 如下: const CommentListWithSubscription = withSubscription(
CommentList,(DataSource) => DataSource.getComments()
);
const BlogPostWithSubscription = withSubscription(
BlogPost,(DataSource,props) => DataSource.getBlogPost(props.id)
});
其中第一个参数是一个组件,第二参数则是我们在 // This function takes a component...
function withSubscription(WrappedComponent,selectData) {
//返回一个新构建的组件
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: selectData(DataSource,props)
};
}
componentDidMount() {
//进行事件绑定
DataSource.addChangeListener(this.handleChange);
}
componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}
handleChange() {
this.setState({
data: selectData(DataSource,this.props)
});
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}
这个
从 2.不要试图修改原始的组件,使用组合方法在 function logProps(InputComponent) {
InputComponent.prototype.componentWillReceiveProps(nextProps) {
console.log('Current props: ',this.props);
console.log('Next props: ',nextProps);
}
// 对原组件进行的扩展,修改了原组件
return InputComponent;
}
const EnhancedComponent = logProps(InputComponent);
上面的代码就存在几个非常明显的问题了,一个就是原组件在函数中进行改变然后返回,更关键的就是,如果我们的组件中已经写好了一个 所以要避免这种事情,我们就可以采用上面已经提到的包容组件的方式,就是重新创建一个新的组件,让这个组件包裹传递进来的组件,而传递进来的组件则在 function logProps(WrappedComponent) {
return class extends React.Component {
componentWillReceiveProps(nextProps) {
console.log('Current props: ',this.props);
console.log('Next props: ',nextProps);
}
render() {
return <WrappedComponent {...this.props} />;
}
}
}
上面的代码就变得非常正确了。 3.通过包容组件来处理
|