ReactJS为什么需要容器组件和展示组件相分离

JavaScript08

ReactJS为什么需要容器组件和展示组件相分离,第1张

Redux 的 React 绑定库包含了 容器组件和展示组件相分离 的开发思想。明智的做法是只在最顶层组件(如路由操作)里使用 Redux。其余内部组件仅仅是展示性的,所有数据都通过 props 传入。

那么为什么需要容器组件和展示组件相分离呢?

这里有个基本原则:容器组件仅仅做数据提取,然后渲染对应的子组件,记住这个点,Trust me!

看下面这个展示列表的例子,不区分容器和展示组件的情况

// CommentList.jsclass CommentList extends React.Component {  constructor() {    super()   this.state = { comments: [] }

}

componentDidMount() {

$.ajax({      url: "/my-comments.json",      dataType: 'json',      success: function(comments) {        this.setState({comments: comments})

}.bind(this)

})

}

render() {    return <ul>{this.state.comments.map(renderComment)} </ul>

}

renderComment({body, author}) {    return <li>{body}—{author}</li>

}

}

可用性:CommentList不可以复用

数据结构:组件应该对所需要的数据有所预期,但这里其实没有,PropTypes可以很好的做到这一点

那么来看下分离的情况:

// CommentListContainer.jsclass CommentListContainer extends React.Component {

 constructor() {    super()   this.state = { comments: [] }

 }

 componentDidMount() {

   $.ajax({

     url: "/my-comments.json",

     dataType: 'json',

     success: function(comments) {        this.setState({comments: comments})

     }.bind(this)

   })

 }

 render() {    return <CommentList comments={this.state.comments} />

 }

}// CommentList.jsclass CommentList extends React.Component {

 constructor(props) {    super(props)

 }

 render() {

   return <ul>{this.props.comments.map(renderComment)} </ul>

 }

 renderComment({body, author}) {    return <li>{body}—{author}</li>

 }

}

这样就做到了数据提取和渲染分离,CommentList可以复用,CommentList可以设置PropTypes判断数据的可用性

来看下容器组件和展示组件的区别:

展示组件

容器组件

关注事物的展示    关注事物如何工作  

可能包含展示和容器组件,并且一般会有DOM标签和css样式    可能包含展示和容器组件,并且不会有DOM标签和css样式  

常常允许通过this.props.children传递    提供数据和行为给容器组件或者展示组件  

对第三方没有任何依赖,比如store 或者 flux action    调用flux action 并且提供他们的回调给展示组件  

不要指定数据如何加载和变化    作为数据源,通常采用较高阶的组件,而不是自己写,比如React Redux的connect(), Relay的createContainer(), Flux Utils的Container.create()  

仅通过属性获取数据和回调  

很少有自己的状态,即使有,也是自己的UI状态  

除非他们需要的自己的状态,生命周期,或性能优化才会被写为功能组件  

优势:

展示和容器更好的分离,更好的理解应用程序和UI

重用性高,展示组件可以用于多个不同的state数据源

展示组件就是你的调色板,可以把他们放到单独的页面,在不影响应用程序的情况下,让设计师调整UI

迫使你分离标签,达到更高的可用性

<el-table-column>并不是一个dom节点,所以infotext这个类究竟用在哪,需要看下el-table-column这个组件的实现才知道。

用了第三方组件的必然都会遇到你这样的问题,我说下我的解决方法,不一定是好的。

一个vue文件可以写多个<style></style>,加上socped代表本组件的样式,不污染全局。如果需要覆盖第三方组件样式,则不能加scoped,因此需要另写一个<style>.xxx-component{...}</style>,这里用一个大类包裹防止污染全局。

接着,我用比较笨的方法(有好的方法请告知),就是打开f12检查究竟要覆盖哪些样式,然后写在没有加scoped的style里即可。

其实一些好的第三方UI库都有提供自定义样式的方法的,这样实现起来才是最便捷的。

在JS开发中,如果要确保界面在下拉组件下面,可以使用以下几种方法:

1.使用CSS中的z-index属性,将下拉组件的z-index值设置为较低值,而界面元素的z-index值设置为较高值。这样就能确保界面元素覆盖在下拉组件上。

2.使用JavaScript代码控制下拉组件的显示和隐藏,在下拉框显示时,将界面元素的可见性设置为不可见,在下拉框隐藏时,将界面元素的可见性设置为可见。