Отменить повторный рендеринг элементов в React, при добавлении нового элемента в массив
Подскажите пожалуйста, как предотвратить повторный рендеринг всех элементов, при добавлении нового в массив. Чтобы рендеринг был только последнего добавленного, без перерендеринга предыдущих.
const [messages, setMessages] = useState([]);
const addMessage = (data) => {
setMessages([...messages, data]);
};
Рендеринг элементов произвожу через map.
{messages.map((message, index) => {
return(<li key={index}>{message}</li>)
)}
Спасибо!
Ответы (1 шт):
@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);