5 способов избежать повторного рендеринга компонентов React

0 1

1. Мемоизация с использованием хуков useMemo() и UseCallback()

Мемоизация позволяет вашему коду перерисовывать компоненты только в случае изменения свойств. С помощью этой методики разработчики могут избежать ненужного рендеринга и снизить вычислительную нагрузку в приложениях. React предоставляет два хука для реализации мемоизации: useMemo() и UseCallback().

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

useMemo()

Чтобы понять, как мы можем использовать хук useMemo(), давайте рассмотрим пример умножения двух чисел.

5 способов избежать повторного рендеринга компонентов React

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас! JavaScript const multiply = (x,y) => { return x*y }

123const multiply = (x,y) => {  return x*y}

Вышеупомянутая функция будет вычислять результат и повторно отображать компонент каждый раз, когда она вызывается, независимо от входных данных. Но, если мы используем хук useMemo(), мы можем избежать повторного рендеринга компонента, если входные данные одинаковы, и сохранить результат в кеше.

JavaScript const cachedValue = useMemo(() => multiply(x, y), [x, y])

1const cachedValue = useMemo(() => multiply(x, y), [x, y])

Теперь вычисленный результат сохраняется в переменной cachedValue, и хук useMemo() будет возвращать его каждый раз, если входные данные не изменились.

UseCallback()

UseCallback() — еще один React Hook для реализации мемоизации. Но, в отличие от useMemo(), он не кэширует результат. Вместо этого он запоминает предоставленную ему функцию обратного вызова. Например, рассмотрим компонент со списком кликабельных элементов.

JavaScript import { useCallback } from ‘react’; export function MyParent({ term }) { const onClick = useCallback(event => { console.log(‘Clicked Item : ‘, event.currentTarget); }, [item]); return ( <Listitem={item} onClick={onClick} /> ); }

123456789101112import { useCallback } from ‘react’; export function MyParent({ term }) {  const onClick = useCallback(event => {    console.log(‘Clicked Item : ‘, event.currentTarget);  }, [item]);   return (    <Listitem={item} onClick={onClick}    />  );}

В приведенном выше примере useCallBack() запоминает обратный вызов onClick. Таким образом, он не будет повторно отображать компонент, если пользователь снова и снова кликает на один и тот же элемент.

2. Оптимизация вызовов API с помощью React Query

Хук useEffect() обычно используется для операций асинхронной выборки данных в приложениях React. Однако функция useEffect() запускается и извлекает данные при каждом рендеринге, и в большинстве случаев она продолжает загружать одни и те же данные.

В качестве решения мы можем использовать библиотеку React Query для кэширования данных ответа. Когда мы делаем вызов API, React Query сначала возвращает данные из кеша, прежде чем продолжить запрос. Затем, она извлекает данные с сервера и, если новых данных нет, предотвращает повторный рендеринг компонента.

JavaScript import React from ‘react’ import {useQuery} from ‘react-query’ import axios from ‘axios’async function fetchArticles(){ const {data} = await axios.get(URL) return data } function Articles(){ const {data, error, isError, isLoading } = useQuery(‘articles’, fetchArticles) if(isLoading){ return <div>Loading…</div> } if(isError){ return <div>Error! {error.message}</div> } return( <div> … </div> ) } export default Articles

1234567891011121314151617181920212223import React from ‘react’import {useQuery} from ‘react-query’import axios from ‘axios’async function fetchArticles(){  const {data} = await axios.get(URL)      return data} function Articles(){  const {data, error, isError, isLoading } = useQuery(‘articles’, fetchArticles)   if(isLoading){    return <div>Loading…</div>  }  if(isError){    return <div>Error! {error.message}</div>  }  return(    <div>      …    </div>  )}export default Articles

Библиотека React Query имеет более 600 тысяч загрузок NPM в неделю и более 1,3 тысячи звезд GitHub.

3. Создание мемоизированных селекторов с помощью Reselect

Reselect — это сторонняя библиотека React для создания запоминаемых селекторов. Она обычно используется с хранилищами Redux и обладает замечательными функциями, позволяющими сократить количество ненужных повторных рендерингов.

Селекторы повторного выбора способны вычислять производные данные.

5 способов избежать повторного рендеринга компонентов React

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

Селекторы повторного выбора не пересчитываются, если их аргументы не меняются.

Их можно использовать в качестве входных данных для других селекторов.

Reselect предоставляет API под названием createSelector и может генерировать мемоизированные функции секторов. Для лучшего понимания рассмотрим пример, приведенный ниже.

JavaScript import { createSelector } from ‘reselect’ … const selectValue = createSelector( state => state.values.value1, state => state.values.value2, (value1, value2) => value1 + value2 ) …

12345678import { createSelector } from ‘reselect’ …const selectValue = createSelector(  state => state.values.value1,  state => state.values.value2,  (value1, value2) => value1 + value2)…

Здесь createSelector принимает на вход 2 селектора и возвращает мемоизированную версию. Селекторы не будут вычисляться снова с этой мемоизированной версией, пока значения не будут изменены.

Библиотека Reselect имеет более 2 миллионов еженедельных загрузок NPM и более 18,4 тыс. звезд GitHub.

4. Замена useState() на useRef()

Хук useState() широко используется в приложениях React для повторного рендеринга компонентов при изменении состояния. Однако есть сценарии, в которых нам нужно отслеживать изменения состояния без повторного рендеринга компонентов.

Если мы воспользуемся хуком useRef(), то сможем отслеживать изменения состояния, не вызывая повторного рендеринга компонентов.

JavaScript function App() { const [toggle, setToggle] = React.useState(false) const counter = React.useRef(0) console.log(counter.current++) return ( <button onClick={() => setToggle(toggle => !toggle)} > Click </button> ) } ReactDOM.render(<React.StrictMode><App /></React.StrictMode>, document.getElementById(‘mydiv’))

1234567891011function App() {  const [toggle, setToggle] = React.useState(false)  const counter = React.useRef(0)  console.log(counter.current++)  return (    <button onClick={() => setToggle(toggle => !toggle)} >       Click     </button>  )}ReactDOM.render(<React.StrictMode><App /></React.StrictMode>, document.getElementById(‘mydiv’))

В приведенном выше примере есть переключатель, который повторно отображает компонент каждый раз, когда значение изменяется. Но counter сохраняет свое значение, так как это изменяемая ссылка. Поскольку мы используем useRef(), это вызовет только один рендеринг. Однако, если мы используем useState(), это вызовет 2 рендеринга при каждом переключении.

5. Использование React Fragments

Если вы раньше работали с React, то знаете, что React требует оборачивать компоненты одним родительским элементом. Хотя это не касается непосредственно повторного рендеринга, знаете ли вы, что это влияет на общее время рендеринга компонента?

В качестве решения вы можете использовать React Fragments для упаковки компонентов, и это уменьшит нагрузку на DOM, что приведет к более быстрому времени рендеринга и уменьшению использования памяти.

JavaScript const App= () => { return ( <React.Fragment><p>Hello<p/><p>World<p/></React.Fragment> ); };

12345const App= () => {  return (    <React.Fragment><p>Hello<p/><p>World<p/></React.Fragment>  );};

Заключение

В этой статье я обсудил 5 различных методов предотвращения ненужного повторного рендеринга в компонентах React. Большинство этих решений используют кэширование, вы можете использовать встроенные хуки React или сторонние библиотеки для их реализации.

Кроме того, эти методы улучшат производительность вашего приложения, предотвращая ненужный повторный рендеринг и уменьшая нагрузку на память. Я надеюсь, что вы нашли статью полезной. Спасибо за чтение!

Автор: Chameera Dulanga

Источник: webformyself.com

Оставьте ответ