(1) 传数据: 首选, 因为代码少呀, 使用的时候只需要传入一个数组/对象/其他数据类型, 通过 this.props
(2) 传入jsx: 这种方式更加灵活但是重复代码更多, 通过 this.props.children
传入jsx的话也可以通过props来传, 因为props可以接受一个组件或者jsx变量
(1) thead: 表头的就是为了展示几个标题, 它的结构就是
, 里面放的内容也只会是字符串, 不会嵌套jsx, 所以它可以用第一种传数据的方式Id
(2) tbody: 因为列表主体内容各不相同, 而且可以嵌套, 例如: 里面放按钮, 然后按钮有自己的点击事件, 这些事件的逻辑肯定应该写在父组件, 所以整个 tbody, 都应该让父组件去定义, 然后传给子组件
这样肯定不能传数据, 需要传入jsx
(1) 写好静态UI
(2) 考虑组件的状态: state prop
(3) 考虑组件的交互方式
import React from 'react';
class TableList extends React.Component {
constructor (props) {
super(props);
this.state = {
isFirstLoad: true
}
}
componentWillReceiveProps () {
// 列表只有在第一次加载的时候isFirstLoad为true -> 表示正在加载,其他为false
this.setState({
isFirstLoad: false
})
}
render () {
// 表头字段
let tableHeader = (
{
this.props.tableHeads.map(
(tableHead, index) => {
if (typeof tableHead === 'string') {
return { tableHead }
}
else if (typeof tableHead === 'object') {
return { tableHead.name }
}
}
)
}
);
let listBody = this.props.children;
// 列表加载时信息
let listInfo = (
{ this.state.isFirstLoad ? '正在加载...' : '没有找到相应的结果~' }
);
return (
{ tableHeader }
{
listBody.length ? listBody : listInfo
}
);
}
}
export default TableList;
render () {
let tbody = (
this.state.list.map((item, index) => {
return (
{ item.id }
{ item.username }
{ item.email }
{ item.phone }
{ new Date(item.createTime).toLocaleString() }
);
})
);
return (
{ tbody }
this.onPageNumChange(pageNum)} />
);
}
这个组件由thead + tbody组成
thead: 是父组件通过props传入一个数组, ['ID', '用户名', '邮箱', '电话', '注册时间']
tbody: 是父组件通过props.children传入一个jsx
let tbody = (
this.state.list.map((item, index) => {
return (
{ item.id }
{ item.username }
{ item.email }
{ item.phone }
{ new Date(item.createTime).toLocaleString() }
);
})
);
两个判断:
this.props.chilren为空显示listInfo, 不为空显示this.props.children
isFirstLoad为true, listInfo里面文字是"正在加载", 否则显示"没有请求到数据"
(1) 父组件每次刷新或者进入都是加载2次, 第一次加载DOM, 这个时候里面的数据都是默认的数据, 在 componentDidMount
, 也就是当所有的DOM加载完成后去请求数据, 拿到数据后放入state, state改变页面重新渲染
(1) 子组件也是加载两次, 它的render函数会执行2次, componentWillReceiveRrops
, 只会执行一次
第一次: 页面挂载, 父组件还没请求数据, 它传给子组件的都是state里面的默认数据, 这个时候render函数会执行, 子组件拿到的this.props.children就是空的, 长度为0, tbody里面就显示listInfo, 子组件根据isFirstLoad来判断listInfo显示的信息, 默认值是true, 所以listInfo就显示的是"正在加载"
第二次: 父组件请求到数据后, 放入state, state改变导致父组件重新渲染, 然后把新的数据传给子组件, 然后导致子组件重新渲染, 然后子组件会先调用componentWillReceiveRrops
函数, 把isFirstLoad = false
, 但是这时候this.props.children里面有数据了, 所以直接显示它里面的数据, 虽然listInfo里面的提示内容是"没有请求到数据", 但是它不显示
当父组件请求数据失败的时候, this.props.children是空的, 所以显示listInfo, 这个时候isFirstLoad已经被改成了false, 所以listInfo就是"没有请求到数据"
(1)componentWillReceiveRrops
它在组件第一次挂载时候不会被执行, 当更新的时候它会执行
(2) 如果一个组件通过异步请求获取数据然后填充数据, 那么这个组件的render函数会被执行2次, 第一次是挂载, 第二次是更新