React native 在React Native中,将数据源加载到listView的正确方法是什么 在React Native中将数据源加载到listview的正确方法是什么?
目前,我正在像下面这样做。这是可行的,但在我所有的列表中采用这个概念之前,我想了解一些信息。这是一个好的方法吗?我的原始数据保存在一个不可变的.List中 对于不习惯Immutable.js的读者:使用普通数组的区别在于我们需要调用list.get(rowId),而不是简单地调用array[rowId]。我们还需要将索引列表转换为数组keySeq().toArray() 在constructur中,我使用一个数据源初始化this.state,我还使用一个单独的函数(cloneDataSource)在该数据源上执行数据的初始克隆: 用于克隆数据行的函数从构造函数和componentWillReceiveProps调用。此特定列表视图有两个硬编码部分:React native 在React Native中,将数据源加载到listView的正确方法是什么 在React Native中将数据源加载到listview的正确方法是什么?,react-native,React Native,目前,我正在像下面这样做。这是可行的,但在我所有的列表中采用这个概念之前,我想了解一些信息。这是一个好的方法吗?我的原始数据保存在一个不可变的.List中 对于不习惯Immutable.js的读者:使用普通数组的区别在于我们需要调用list.get(rowId),而不是简单地调用array[rowId]。我们还需要将索引列表转换为数组keySeq().toArray() 在constructur中,我使用一个数据源初始化this.state,我还使用一个单独的函数(cloneDataSource
cloneDataSource(dataSource) {
return dataSource.cloneWithRowsAndSections(
[
this.props.activeProjects,
this.props.inactiveProjects
],
[0,1],
[
this.props.activeProjects.keySeq().toArray(),
this.props.inactiveProjects.keySeq().toArray()
]
)
}
componentWillReceiveProps = (nextProps) => {
this.setState({dataSource: this.cloneDataSource(this.state.dataSource)})
}
我需要调用克隆函数两次,这让我很担心。为什么在componentWillReceiveProps克隆数据还不够?您不能只使用
componentWillReceiveProps
,因为它和您必须使用nextProps
,而不是this.props
。如果您的列表视图
的数据作为道具
来自顶部,您总是需要两个点来更新列表视图.数据源
。一个用于初始渲染,另一个用于即将到来的更新。保持干燥的一种方法是:
constructor(props) {
super(props);
this.state = {
// You can initialize it directly on to the state object
dataSource: new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
getRowData: (dataBlob, sectionId, rowId) => dataBlob[sectionId].get(rowId),
sectionHeaderHasChanged: (s1, s2) => s1 !== s2
}),
};
}
componentWillMount() { // Or `componentDidMount`
// 1. For initial render (note: I'm passing this.props, you'll see why on 2.)
this.updateDataSource(this.props);
}
componentWillReceiveProps(nextProps) {
// 2. For updates
// (note: you must pass `nextProps` because
// `this.props` has not been updated)
this.updateDataSource(nextProps);
}
// Do your thing
updateDataSource(data) {
this.setState({
dataSource: this.state.dataSource.cloneWithRowsAndSections(
[
data.activeProjects,
data.inactiveProjects
],
[0, 1],
[
data.activeProjects.keySeq().toArray(),
data.inactiveProjects.keySeq().toArray()
]
)
});
}
编辑
另外,您应该注意,并非所有的
道具都将出现在nextrops
中,因为只有更改的道具才会出现在newProps
中,因此您应该正确处理,确保道具字段确实存在。太好了,谢谢。做两次感觉有点不对劲,但现在我知道为什么了就没事了。实际上,我一开始在componentWillUpdate中使用了数据克隆,但我将其移动到了构造函数中,以便在创建数据源的地方使用它。这也是为什么我在一个单独的变量中初始化它(不是在这个.state中),这样我就可以以一种干净的方式将它发送到克隆函数。重构也是我丢失“nextrops”的地方。谢谢你抓到了。关于你的编辑:你的意思是我需要在更新函数的顶部有这样的东西吗:if(!data)return;data.activeProjects=data.activeProjects | | this.props.activeProjects;data.inactiveProjects=data.inactiveProjects | | this.props.inactiveProjects;是的,没错。但是,我认为您不需要检查数据是否存在。它将存在,否则生命周期回调将永远不会被调用(不是100%确定,但它会有意义)。非常感谢。你帮了大忙。现在我可以更加自信地继续走这条路了。
constructor(props) {
super(props);
this.state = {
// You can initialize it directly on to the state object
dataSource: new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
getRowData: (dataBlob, sectionId, rowId) => dataBlob[sectionId].get(rowId),
sectionHeaderHasChanged: (s1, s2) => s1 !== s2
}),
};
}
componentWillMount() { // Or `componentDidMount`
// 1. For initial render (note: I'm passing this.props, you'll see why on 2.)
this.updateDataSource(this.props);
}
componentWillReceiveProps(nextProps) {
// 2. For updates
// (note: you must pass `nextProps` because
// `this.props` has not been updated)
this.updateDataSource(nextProps);
}
// Do your thing
updateDataSource(data) {
this.setState({
dataSource: this.state.dataSource.cloneWithRowsAndSections(
[
data.activeProjects,
data.inactiveProjects
],
[0, 1],
[
data.activeProjects.keySeq().toArray(),
data.inactiveProjects.keySeq().toArray()
]
)
});
}