- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个 react 组件,每秒从 redux 存储接收 Prop 。新状态的数组与上一个数组不同。具体来说,每一秒都有一个元素被添加到数组中。例如:在一种状态下,数组是:
[1, 2, 3, 4, 5, 6]
下一个状态
[1, 2, 3, 4, 5, 6, 7]
我的 reducer :
return {
...state,
myList: [ payload, ...state.myList.filter(item => payload.id !== item.id).slice(0, -1) ]
}
现在,在我的 React 组件中,我订阅了这个状态,并且对于每次更改,列表都会重新呈现。
import React, { Component } from 'react';
import MyRow from './MyRow';
class MyList extends Component {
render() {
return (
<div>
{this.props.myList.map((list, index) => (
<MyRow key={list.id} data={list}/>
))}
</div>
);
}
}
function select({ myList }) {
return { myList };
}
export default connect(select)(MyList);
在 MyRow.js 中
import { PureComponent } from 'react';
class MyRow extends PureComponent {
render() {
const data = this.props.data;
return (
<div>
{data.id} - {data.name}
</div>
);
}
}
export default MyRow;
现在,我的问题是:重新渲染已经渲染过的每个元素对我来说成本很高。 MyRow 大量使用样式组件和其他昂贵的操作。这导致 React 在状态更新时每秒重新渲染整个列表。如果更新不到 1 秒,比如每秒 4 次更新,情况会变得更糟。在这种情况下,React 应用程序会崩溃。
有没有办法只将新添加的项目添加到列表中而不重新渲染整个列表?
谢谢
最佳答案
您正在使用 PureComponent ,做浅比较,然后你的组件 MyRow
应该不在添加的每个新项目上重新呈现(请按照我下面的代码示例)。
Is there any way to only add the newly added item to the list and not re-render the whole list?
根据您的问题 - 是的,使用 PureComponent
应该只渲染 1 次新项目:
这是 React's docs 的内容说:
If your React component’s render() function renders the same result given the same props and state, you can use React.PureComponent for a performance boost in some cases.
PureComponent
的代码示例:您可以查看我为您制作的代码示例。
您会看到 Item
组件总是只渲染 1 次,因为我们使用 React.PureComponent
.为了证明我的说法,每次Item
渲染后,我添加了当前渲染时间。从示例中您将看到 Item
Rendered at:
时间总是相同的,
因为它只渲染了 1 次。
const itemsReducer = (state = [], action) => {
if (action.type === 'ADD_ITEM') return [ ...state, action.payload]
return state
}
const addItem = item => ({
type: 'ADD_ITEM',
payload: item
})
class Item extends React.PureComponent {
render () {
// As you can see here, the `Item` is always rendered only 1 time,
// because we use `React.PureComponent`.
// You can check that the `Item` `Rendered at:` time is always the same.
// If we do it with `React.Component`,
// then the `Item` will be rerendered on each List update.
return <div>{ this.props.name }, Rendered at: { Date.now() }</div>
}
}
class List extends React.Component {
constructor (props) {
super(props)
this.state = { intervalId: null }
this.addItem = this.addItem.bind(this)
}
componentDidMount () {
// Add new item on each 1 second,
// and keep its `id`, in order to clear the interval later
const intervalId = setInterval(this.addItem, 1000)
this.setState({ intervalId })
}
componentWillUnmount () {
// Use intervalId from the state to clear the interval
clearInterval(this.state.intervalId)
}
addItem () {
const id = Date.now()
this.props.addItem({ id, name: `Item - ${id}` })
}
renderItems () {
return this.props.items.map(item => <Item key={item.id} {...item} />)
}
render () {
return <div>{this.renderItems()}</div>
}
}
const mapDispatchToProps = { addItem }
const mapStateToProps = state => ({ items: state })
const ListContainer = ReactRedux.connect(mapStateToProps, mapDispatchToProps)(List)
const Store = Redux.createStore(itemsReducer)
const Provider = ReactRedux.Provider
ReactDOM.render(
<Provider store={Store}>
<ListContainer />
</Provider>,
document.getElementById('container')
)
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.7/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.26.0/polyfill.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
MyRow
引起的重新渲染,请找出重新渲染的原因,因为它不应该发生,因为PureComponent
用法。
myList: [ ...state.myList, payload ]
key
到您的项目组件 <MyRow key={list.id} data={list} />
.如果key
或 data
Prop 被改变,那么组件将被重新渲染。 这里有一些其他的库,它们代表列表的高效呈现。我相信他们会给我们一些替代方案或见解:
关于javascript - React/Redux 渲染一个每秒更新的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50430459/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!