Почему React-компонент не рендерится, разбираем все причины и решения

mr. Cooper 2 часа назад Веб-разработка
Почему React-компонент не рендерится, разбираем все причины и решения

Открыл DevTools, а на странице пусто или вместо компонента - белый экран? Знакомая боль почти каждого React-разработчика, от джуна до миддла. Проблема в том, что причин у этого может быть добрый десяток: от опечатки в условии до сломанного состояния стора. В этой статье разберём, почему React-компонент не рендерится, как быстро найти причину и что делать, чтобы это не повторялось.

Статья поможет тем, кто:

  • получил пустой экран или ошибку вместо UI;

  • видит, что компонент «не обновляется» при изменении пропсов или состояния;

  • ловит React не рендерит компонент в консоли без понятной ошибки.

Вы узнаете, какие причины встречаются чаще всего, как их диагностировать и какие конкретные шаги исправят ситуацию.

Что это такое

«Компонент не рендерится» - собирательное название для нескольких разных симптомов:

  1. Полный белый экран - обычно сигнал необработанной ошибки JavaScript, из-за которой React прекращает рендеринг всего дерева.

  2. Компонент монтируется, но ничего не показывает - условный рендеринг возвращает null или пустую строку там, где не должен.

  3. Компонент рендерится один раз и потом не обновляется - проблема не в рендере как таковом, а в том, что React не видит изменений и не запускает повторный рендер (re-render).

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

Почему возникает / зачем нужно разбираться

React рендерит компонент, когда:

  • он впервые монтируется в DOM;

  • изменилось его состояние (useState, useReducer);

  • изменились пропсы, которые он получает;

  • изменился контекст (useContext), на который он подписан;

  • родитель перерендерился (если нет мемоизации).

Если хотя бы одно из этих условий не выполняется или выполняется «незаметно» для React (например, мутация объекта вместо создания нового), компонент не обновится - даже если данные внутри фактически изменились.

Понимание этого механизма - ключ к быстрой диагностике: вы ищете не «баг вообще», а конкретное звено в этой цепочке, которое сломалось.

Частые ошибки и проблемы

1. Незамеченная ошибка JavaScript

Самая частая причина белого экрана. Ошибка в рендере одного компонента «роняет» всё дерево, если нет Error Boundary.

2. Неправильный экспорт/импорт

// component.jsx
export default function Card() { ... }

// App.jsx - ошибка: импорт не дефолтный
import { Card } from './component'; // undefined!

React в таком случае либо ничего не покажет, либо выдаст ошибку Element type is invalid.

3. Условный рендеринг возвращает falsy-значение не туда, куда нужно

{count && <Counter value={count} />}

Если count равен 0, в DOM попадёт текст «0» вместо ожидаемого «ничего» - частая, хоть и обратная ситуация, но из той же категории ошибок.

4. Мутация состояния напрямую

// Неправильно - React не увидит изменения
state.items.push(newItem);
setState(state);

// Правильно
setState({ ...state, items: [...state.items, newItem] });

React сравнивает ссылки, а не глубокое содержимое объекта. Мутация - самая частая причина, почему React не обновляет компонент при изменении состояния.

5. Ключи (key) перепутаны или отсутствуют в списках

Без уникальных key React может неправильно сопоставлять элементы между рендерами, из-за чего часть списка визуально «не обновляется».

6. Компонент не возвращает JSX

function Profile() {
  console.log('rendering'); // забыли return
}

Функция без return вернёт undefined, и React ничего не отрисует, но и явной ошибки может не быть.

7. Неправильное условие монтирования

Опечатка в проверке if (isLoading) return null без учёта реального состояния флага - компонент «застревает» в невидимом состоянии.

8. Проблемы с React.memo / useMemo / useCallback

Излишняя или неправильная мемоизация может «заморозить» компонент, и он перестанет реагировать на новые пропсы.

Как исправить: пошаговое решение

Шаг 1. Откройте консоль браузера Большинство случаев белого экрана сопровождаются ошибкой в консоли. Прочитайте её внимательно - React обычно указывает конкретный компонент и строку.

Шаг 2. Проверьте, монтируется ли компонент вообще

function MyComponent() {
  console.log('MyComponent render');
  return <div>Hello</div>;
}

Если лог не появляется - компонент даже не вызывается. Проверьте маршрутизацию, условный рендеринг родителя и корректность импорта.

Шаг 3. Проверьте, что компонент действительно возвращает JSX Убедитесь, что есть return, и что условная логика не «съедает» вывод.

Шаг 4. Используйте React DevTools Откройте вкладку Components, найдите компонент в дереве. Если его нет - проблема на уровне родителя или маршрутизации. Если есть, но пуст - проблема в самом рендере.

Шаг 5. Проверьте обновление состояния и пропсов В DevTools посмотрите, меняются ли props/state компонента при действиях пользователя. Если нет - ищите мутацию состояния или неправильную привязку колбэков.

Шаг 6. Добавьте Error Boundary

class ErrorBoundary extends React.Component {
  state = { hasError: false };
  static getDerivedStateFromError() {
    return { hasError: true };
  }
  componentDidCatch(error, info) {
    console.error(error, info);
  }
  render() {
    if (this.state.hasError) return <h1>Что-то пошло не так</h1>;
    return this.props.children;
  }
}

Это покажет вам ошибку, которая раньше «молча» рушила всё дерево.

Шаг 7. Проверьте ключи в списках Убедитесь, что key уникален и стабилен (не используйте индекс массива, если порядок элементов может меняться).

Шаг 8. Проверьте зависимости хуков В useEffect, useMemo, useCallback проверьте массив зависимостей - забытая зависимость часто приводит к «застывшему» UI с устаревшими данными.

Примеры

Пример 1: компонент рендерится, но список не обновляется

const [items, setItems] = useState([]);

function addItem(item) {
  items.push(item); // мутация - React не перерендерит
  setItems(items);
}

Исправление:

function addItem(item) {
  setItems(prev => [...prev, item]);
}

Пример 2: типичная ошибка консоли

Warning: Each child in a list should have a unique "key" prop.

Решение - добавить key={item.id} вместо отсутствующего ключа или индекса.

Пример 3: ошибка импорта

Uncaught TypeError: Element type is invalid: expected a string... but got: undefined

Чаще всего значит, что компонент импортирован неправильно (default vs named export) либо файл экспортирует undefined из-за циклического импорта.

Часто задаваемые вопросы (FAQ)

Компонент не рендерится, но ошибок в консоли нет - что делать? Проверьте через console.log сам факт вызова функции компонента и значение, которое она возвращает. Часто причина - условие, которое возвращает null, либо проблема в родительском компоненте, который вообще не рендерит дочерний элемент.

Почему React не обновляет компонент при изменении объекта в состоянии? React использует поверхностное сравнение (Object.is) для пропсов и состояния. Если вы мутируете объект напрямую, ссылка остаётся той же, и React не видит изменений. Всегда создавайте новый объект или массив через spread-оператор.

Что делать, если компонент рендерится дважды? В режиме разработки React.StrictMode намеренно вызывает рендер дважды для выявления побочных эффектов. В продакшен-сборке этого не происходит - это не баг.

Почему useEffect не срабатывает при обновлении компонента? Скорее всего, неправильно указан массив зависимостей. Пустой массив [] означает «выполнить только при монтировании», отсутствие массива - «при каждом рендере».

React-компонент не рендерится после установки новой библиотеки - в чём может быть причина? Проверьте совместимость версий React и библиотеки, наличие конфликтов в package.json, а также корректность экспорта компонентов из самой библиотеки.

Как понять, что виноват именно React.memo? Временно уберите обёртку React.memo и проверьте, появляется ли обновление. Если да - проблема в функции сравнения пропсов или в том, что пропсы передаются «по значению», но содержимое объекта меняется без смены ссылки.

Почему компонент рендерится в DevTools, но невидим на странице? Скорее всего, дело в CSS: display: none, нулевая высота/ширина родителя, opacity: 0 или элемент вне видимой области экрана.

Может ли проблема быть в Server-Side Rendering (Next.js)? Да. Несовпадение разметки между сервером и клиентом (hydration mismatch) может привести к тому, что часть UI не появится или появится с задержкой. Проверьте консоль на предупреждения о гидратации.

Полезные советы и лучшие практики

  • Всегда оборачивайте корневые части приложения в Error Boundary - это превращает «тихий» белый экран в понятное сообщение об ошибке.

  • Никогда не мутируйте состояние напрямую - используйте spread-операторы или библиотеки вроде Immer.

  • Используйте React DevTools Profiler, чтобы видеть, какие компоненты перерендериваются и почему.

  • Включайте React.StrictMode в разработке - он помогает выявлять побочные эффекты заранее.

  • Для списков всегда используйте стабильный уникальный key, в идеале - id из данных, а не индекс массива.

  • Проверяйте версии React и сопутствующих библиотек на совместимость после каждого обновления зависимостей.

  • Логируйте рендеры временно через console.log на этапе отладки - это самый быстрый способ понять, вызывается ли функция компонента вообще.

Итог

Если React-компонент не рендерится, в 90% случаев причина одна из: необработанная ошибка JS, мутация состояния напрямую, неправильный импорт/экспорт, отсутствующий return, или проблема с условным рендерингом. Системный подход - проверить консоль, убедиться, что компонент монтируется, посмотреть в React DevTools на пропсы и состояние - приводит к решению быстрее, чем хаотичный перебор гипотез. Возьмите за привычку оборачивать приложение в Error Boundary и никогда не мутировать состояние напрямую - это закроет большинство подобных проблем ещё до их появления.

Комментарии

Пока нет комментариев. Будьте первым, кто напишет.

Чтобы оставить комментарий, войдите в аккаунт.

Похожие статьи