是否可以强制ListView重新渲染,即使dataSource中的数据没有改变?我在我的应用程序的标签栏中有一个ListView,我希望每次选择该标签时都重绘它,无论数据是相同还是已经更改。
this.state = {
data: props.data,
dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
}
componentWillMount() {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(nextProps.data)
})
}
render() {
<ListView
dataSource={this.state.data}
renderRow={this._renderRow}
/>
}
我尝试使用rowHasChanged
参数,但这没有帮助。任何帮助将不胜感激
答案 0 :(得分:32)
因此,根据我的理解,您的用例是因为value
更改而重新呈现ListView的所有行。我不知道value
是什么,由你决定,但我会用value
来解释我的答案:
有几种方法可以解决这个问题。各有利弊:
<ListView key={value} ... />
!!它告诉React ListView需要在值更改时重新呈现(它将被卸载,重新安装)。this.setState({
dataSource: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !==
r2 }).cloneWithData(this.props.data)
});
value
并正确实现rowHasChanged。例如:(r1, r2) => r1.value !== r2.value && r1.data !== r2.data
(&lt; - 这只是表示数据的一种可能方式,你必须选择你的格式,我只是假设你用nextProps.data.map(data => ({ data, value })
克隆了dataSource。)对我来说,第三个也是最后一个解决方案是最好的,因为:
value
s)这是我就该主题提出的另一个答案:
What are the exact inputs to rowHasChanged in ListView.DataSource
答案 1 :(得分:2)
“更新”这个的最好方法是克隆有问题的数据项,而不是像arr[i] = { ...arr[i], someKey: newValue }
已经暗示的那样进行标记黑客攻击。而不是更新单个项目,通过克隆来更改“指针”本身。
对于此特定问题,请更新数组中的项目。
{{1}}
这将用“newValue”替换“someKey”属性,当前行将有一个新指针。
这是一个很好的资源,可以了解现代JavaScript中对于本机用途的不可变性:https://wecodetheweb.com/2016/02/12/immutable-javascript-using-es6-and-beyond/
答案 2 :(得分:0)
您可以调用this.forceUpdate()强制重新渲染。
您可以在附加到选项卡的简单onClick
处理程序中执行此操作。
更多信息here, on the official docs
但是,如果还有其他规则规定是否应该有更新,您可以尝试将dataSource
替换为新的,使其具有新的引用。这也将使其更新。
的内容
this.setState({ data : newDataSource… });
答案 3 :(得分:0)
这可能有点矫枉过正,但我只是替换了componentDidUpdate上的数据源(也许这对性能有害?我不知道哈哈)
componentWillMount() {
this.ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.dataSource = this.ds.cloneWithRows(this.props.shiftsList);
}
componentDidUpdate() {
this.ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.dataSource = this.ds.cloneWithRows(this.props.shiftsList);
}
答案 4 :(得分:0)
我知道我有点晚了,但我确信这仍然有用。对此有一个更简单的方法......杰森提供的第一个例子无论如何都是一个很好的解决方案,但我想的是那些容易混淆的人。如果是这样,请使用此功能。
// On component initalization
componentWillMount() {
this.UpdateData();
}
// When the component updates
componentDidUpdate() {
if (this.state.data != this.props.data)
this.UpdateData();
}
// Function to update the ListView component data
UpdateData() {
var source = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.setState({
data: this.props.data,
dataSource: source.cloneWithRows(this.props.data)
});
}
我还建议在您的应用程序中实现Redux。这样,您可以将新的,更新的数组值存储在reducer中,然后将其存储在本地状态,然后在componentDidUpdate函数中使用if语句来确定数据是否已更新。
React调试器不记录任何基于性能的投诉或警告......