Отменить повторный рендеринг элементов в React, при добавлении нового элемента в массив

Подскажите пожалуйста, как предотвратить повторный рендеринг всех элементов, при добавлении нового в массив. Чтобы рендеринг был только последнего добавленного, без перерендеринга предыдущих.

const [messages, setMessages] = useState([]);

  const addMessage = (data) => {
    setMessages([...messages, data]);
  };

Рендеринг элементов произвожу через map.

{messages.map((message, index) => {
   return(<li key={index}>{message}</li>)
)}

Спасибо!


Ответы (1 шт):

Автор решения: Sire IMPACTUS

@SwaD, у меня список образуется и каждый раз при добавлении нового элемента в него, весь список приходится перерендеривать. Это заметно визуально и по оптимизации, я считаю не очень. Поэтому думал, что можно неизменившиеся элементы не рендерить заново каждый раз.

Проблему тут не в рендере списка. У тебя либо происходит очень тяжелый пересчет стилей, либо где-то утечка памяти.

Лучше правильно назначить key и не использовать способ, представленный ниже, но если тебе прям очень надо, то вот:

const List = () => {
  const [messages, setMessages] = useState([]);

  return <ViewList list={messages} />
}

const ViewList = React.memo((props: {list: any[]}) => {
  return <Fragment>
    {props.messages.map((message, index) => {
       return(<li key={index}>{message}</li>)
    )};
  </Fragment>
}, (oldProps, newProps) => {
  return oldProps !== newProps // default

  //тут можешь сравнивать lists и решать, нужно ли тебе сейчас перерендерить список или нет.

  return false // рендера не будет
  return true // будет перерендер
})

ИЛИ

const List = () => {
  const [messages, setMessages] = useState<string[]>([]);

  return <Fragment>{messages.map(it => <ListItem key={it} message={it} />)}</Fragment>
}

const ListItem = React.memo((props: {message: string}) => {
  return <li>{props.message}</li>
}, (prev, _new) => prev?.message !== _new?.message);

Документация: https://reactjs.org/docs/react-api.html#reactmemo

const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});

React.memo — это компонент более высокого порядка.

Если ваш компонент отображает один и тот же результат с теми же параметрами, вы можете обернуть его вызовом React.memo для повышения производительности в некоторых случаях путем запоминания результата. Это означает, что React пропустит рендеринг компонента и повторно использует последний результат рендеринга.

React.memo проверяет только изменения свойств. Если ваш функциональный компонент, завернутый в React.memo, имеет в своей реализации useState, useReducer или useContext Hook, он все равно будет перерисовываться при изменении состояния или контекста.

По умолчанию он будет только поверхностно сравнивать сложные объекты в объекте реквизита. Если вы хотите контролировать сравнение, вы также можете указать пользовательскую функцию сравнения в качестве второго аргумента.

function MyComponent(props) {
  /* render using props */
}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(MyComponent, areEqual);
→ Ссылка