Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
React Native-在数据未更改时强制重新呈现ListView_Listview_Reactjs_React Native - Fatal编程技术网

React Native-在数据未更改时强制重新呈现ListView

React Native-在数据未更改时强制重新呈现ListView,listview,reactjs,react-native,Listview,Reactjs,React Native,即使数据源中的数据没有更改,也可以强制ListView重新呈现吗?我在我的应用程序的选项卡栏中有一个ListView,我希望它在每次选择该选项卡时都重新绘制,无论数据是否相同或已更改 this.state = { data: props.data, dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}) } componentWillMount() { this.setState(

即使数据源中的数据没有更改,也可以强制ListView重新呈现吗?我在我的应用程序的选项卡栏中有一个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}
  />
}
this.state={
数据:道具数据,
数据源:新建ListView.dataSource({rowHasChanged:(r1,r2)=>r1!==r2})
}
组件willmount(){
这是我的国家({
dataSource:this.state.dataSource.cloneWithRows(nextrops.data)
})
}
render(){
}

我尝试使用
rowHasChanged
参数,但没有任何帮助。任何帮助都将不胜感激

您可以调用此.forceUpdate()强制重新渲染

您可以在附加到选项卡的简单
onClick
处理程序中执行此操作

更多信息

但是,如果有其他规则规定是否应该更新,您可以尝试用新的数据源替换
数据源
,使其具有新的引用。这也将使它更新

类似于


this.setState({data:newDataSource…})

因此,据我所知,您的用例是由于
值的更改而重新呈现ListView的所有行。我不知道
value
是什么,由您决定,但我将用
value
来解释我的答案:

有几种方法可以解决这个问题。各有利弊:

  • 简单方法:只要
    !!它告诉React,当值更改时,ListView需要重新呈现(将卸载、重新装载)
  • “哈奇方式”。替换为新的数据源。
    this.setState({
    dataSource:new ListView.dataSource({rowHasChanged:(r1,r2)=>r1==
    r2}).cloneWithData(this.props.data)
    });
    
  • (imo)最佳实践方式:在数据中,合并
    ,并正确实现行更改。例如:
    (r1,r2)=>r1.value!==r2.value和r1.data!==r2.数据
    ({data,value})

对我来说,第三个也是最后一个解决方案是最好的,因为:

  • 它可以很好地扩展到更多的重新渲染条件(其他
    s)
  • 可能只有部分行需要重新渲染,在这种情况下,不应该为了更好的性能而重新渲染所有行
以下是我在这个问题上给出的另一个答案:

使用不变性方法 “更新”的最佳方法是克隆有问题的数据项,而不是像
r1!==r2已经在暗示。通过克隆更改“指针”本身,而不是更新单个项目

对于此特定问题,请按如下方式更新数组中的项

arr[i] = { ...arr[i], someKey: newValue }
这将用“newValue”替换“someKey”属性,并且当前行将有一个新指针


这里有一个很好的资源来了解现代JavaScript中的不变性,这些JavaScript可以反应本机使用:

这可能有点过分,但我只是在componentDidUpdate上替换数据源(可能这对性能有害?我不知道哈哈)


我知道我有点晚了,但我相信这仍然是相关的。有一个更简单的方法来解决这个问题。。。Jason提供的第一个例子绝对是一个很好的解决方案,但我想到的是那些容易混淆的人。如果是的话,就用这个

// 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调试器不会记录任何基于性能的投诉或警告…

可能会在选项卡上添加一个
onClick
函数,当该函数被调用时,让它调用渲染函数?谢谢你的回答,我的心都碎了。我不知道r1和r2是指旧的和新的一排。现在变得更有意义了。但愿他们能更好地引用它!有些情况下,“黑客方式”似乎是做你需要的事情的唯一方式。例如,我正在处理一个案例,其中ListView显示的模型列表中的一个模型在应用程序的其他地方被修改。为了显示此更改,我们必须修改整个数据源,因为如果不修改,ListView将什么也不做。这是一个开发人员的意见,认为一个完整的列表应该被视为不变的对象列表中的对象。@ MieaNoKe实现<代码> RoHasStase实际上是选择的机会,如果你认为你的列表对象不变或不可变。这真的取决于你去实现它,只有默认的
r1==r2
是一个支持不可变对象的“开发者意见来自React”,但ListView本身不是这个意见(而不是实验性的WindowedListView)
rowHasChanged
让您可以控制相等函数和数据的不变性。顺便说一句,这整件事是一种性能折衷,也许我们将来会找到更好的东西。比如@mienaikoe说,黑客的方式在当时很有帮助。还要注意的是,答案是
cloneWithData
,这对我不起作用,所以不得不改为
cloneWithRow
谢谢@greI一直认为
r1
r2
是与
排序((a,b)类似的不同行=>…
。现在我意识到它是
prevRow
nextRow
的对比,
rowHasChanged
函数对我来说终于有意义了!
// 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)
    });
}