React独立架构
demo评论功能:
// 含有抽象数据而没有业务逻辑的组件,称之为容器型组件(container component);
// 而没有数据请求逻辑只有业务逻辑的组件,称之为展示型组件(presentational component)。
import React, { Component, PropTypes } from 'react'
// 评论容器组件
class CommentListContainer extends Component {
render() {
return <CommentList data={data} />
}
}
// 评论列表 - 无状态组件
function CommentList({ comments }) {
return (
<ul className='comment-box'>
{comments.map((entry, i) => (
<li key={`reponse-${i}`} className='comment-item'>
<p className='comment-item-name'>{entry.name}</p>
<p className='comment-item-content'>{entry.content}</p>
</li>
))}
</ul>
)
}
// 通过把组件传递给 Promised,就可以实现一个具有请求功能的组件
const Promised = (promiseProp, Wrapped) =>
class extends Component {
constructor(props) {
super(props)
this.state = {
loading: true,
error: null,
value: null
}
}
componentDidMount() {
this.props[promiseProp]
.then(response => response.json())
.then(value => this.setState({ loading: false, value }))
.catch(error => this.setState({ loading: false, error }))
}
render() {
if (this.state.loading) {
return <span>Loading...</span>
} else if (this.state.error !== null) {
return <span>Error: {this.state.error.message}</span>
} else {
const propsWithoutThePromise = dissoc(this.props, promiseProp)
return <Wrapped {...propsWithoutThePromise} {...this.state.value} />
}
}
}
function dissoc(obj, prop) {
let result = {}
for (let p in obj) {
if (p !== prop) {
result[p] = obj[p]
}
}
return result
}
const Wrapper = Promised('comments', CommentListContainer)
ReactDOM.render(<Wrapper comments={fetch('/api/response.json')} />, document.getElementById('root'))