状态更改时如何停止上下文使用者中列表项的重新呈现

时间:2019-08-16 12:38:44

标签: reactjs

我有一个react项目,我使用上下文api管理应用程序的状态。

我有一个带有onClick事件的项目列表,该事件更新了上下文中的状态。

问题在于,当状态更改时,所有项目都会重新渲染,从而导致延迟。

我的问题是,如果未单击,如何阻止其他项目重新呈现。

item.jsx

import React, { useContext } from "react";
import { MainContext } from "../../_context/PresentContext";

const Item = ({item}) => (

 <MainContext.Consumer>
  {({handleSelectItem}) => (
   <div>
    <button onClick={() => handleSelectItem(item)}>{item.name}</button>
   </div>
   )
  }
 </MainContext.Consumer>
)

items.jsx

import React from "react";
import Item from "./Item";


const itemsList = [
 {id: 1, name: 'a'},
 {id: 2, name: 'b'},
 {id: 3, name: 'c'},
 {id: 4, name: 'd'}
]

const Items = () => (
 <div>
  {itemsList.map(i => (
   <Item item={item}/>
  )
 )}
 </div>

)

handleSelectItem函数只是在上下文状态上更新selectedItem,然后在其他组件中使用它

这只是一个演示问题的简单示例。真正的itemsList大约有200个项目。

3 个答案:

答案 0 :(得分:0)

使用Pure Components并在生命周期方法shouldComponentUpdate中进行决策怎么办?

如果您更喜欢使用钩子here is an official documentation,如何使用钩子方法实现上述生命周期方法。

答案 1 :(得分:0)

如果您的class Foo(): nbBUYlist = [] dbBUYlist = [] def tickervalue(self, ticker): # Get with self return (ticker in self.nbBUYlist) + (ticker in dbBUYlist) 全部可序列化,或者您扩展了React.PureComponent并实现了shouldComponentUpdate,则可以扩展Item component props

选项1。

React.Component

选项2

import React, { Component } from "react";
import isEqual from 'lodash.isequal';

export class Item extends Component {
  shouldComponentUpdate(nextProps){
    return !isEqual(this.props.item, nextProps.item);
  }

  render() {
    const { item } = this.props;
    return (
      <MainContext.Consumer>
        {({ handleSelectItem }) => (
          <div>
            <button onClick={() => handleSelectItem(item)}>{item.name}</button>
          </div>
        )}
      </MainContext.Consumer>
    );
  }
}

答案 2 :(得分:0)

  1. 仅当组件的状态/属性以不变的方式更改时,才使用React.memo / PureComponent / shouldComponentUpdate来重新渲染组件,而不是仅仅因为父组件被重新渲染而重新渲染。
  2. 在映射的JSX元素中使用key属性,以便React可以在您的DOM元素之间映射,并且仅在键的值更改时才重新渲染它们,而不是在每次使用组件时都重新渲染整个列表呈现
  3. 箭头函数和对象文字在每次调用时都会返回一个新引用,因此最好在呈现函数之外定义它们,并使用useCallbackuseMemo钩子来记住它们。这样就不会破坏您的PureComponent
  4. 考虑使用react-window https://github.com/bvaughn/react-window来实现虚拟滚动,而不是呈现200个可能对用户隐藏并且不需要在DOM中放慢速度的项目

item.jsx

import React, {memo, useContext } from "react";
import { MainContext } from "../../_context/PresentContext";

const Item = memo(({item}) => (
const handleClick => useCallback(handleSelectItem(item), [item])
const renderConsumer = ({handleSelectItem}) => (
   <div>
    <button onClick={handleClick}>{item.name}</button>
   </div>
   )

 <MainContext.Consumer>
  {renderConsumer()}
 </MainContext.Consumer>
))

items.jsx

import React, {memo} from "react";
import Item from "./Item";

const Items = memo(() => (
 <div>
  {itemsList.map(i => (
   <Item key={i} item={item}/>
  )
 )}
 </div>
))