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

Реагировать

Что такое Реакт?

  • Библиотека пользовательского интерфейса (для создания пользовательских интерфейсов)
  • Компонентная архитектура (разные функции управляют разными частями пользовательского интерфейса)
  • Поток данных в React (односторонний поток данных сверху вниз, компонент к дочерним элементам)
  • Состояние компонента (управление своим состоянием и передача потомкам)
  • Рендеринг + обновление пользовательских интерфейсов, обработка пользовательского ввода

Что такое Компонент?

  • React — это компонентный язык
  • React позволяет создавать сложные пользовательские интерфейсы из небольших и независимых фрагментов кода, называемых «компонентами».
  • Компоненты подобны функциям, которые возвращают HTML-элементы, сообщающие, что должно отображаться на экране (через функцию render()).
  • Компоненты — это основные строительные блоки пользовательского интерфейса, которые можно использовать повторно, вы можете использовать компонент на разных страницах, а компоненты независимы.

В React все является компонентом.

  • Библиотека React as UI (пользовательский интерфейс) зависит от компонентов как от независимого и многократно используемого фрагмента кода, который вы можете использовать в любом месте своего приложения.

Что такое JSX?

  • JSX расшифровывается как JavaScript XML, он позволяет нам писать HTML в React и обладает всеми возможностями JavaScript.
  • JSX упрощает написание и добавление HTML в React и легко создает пользовательские интерфейсы для ваших веб-приложений.
  • Старые браузеры несовместимы с JSX, и React использует babel для преобразования кода в старый синтаксис JS для работы с браузером.

Что такое виртуальный DOM?

  • DOM — это дерево узлов, которое создается браузером после разбора HTML в процессе критического пути рендеринга. React берет копию этого DOM и сохраняет ее в памяти => виртуальный DOM.
  • Когда вы вносите какие-либо изменения или инициируете какое-либо действие, которое в конечном итоге обновит представление, React создает новую копию виртуального DOM и применяет обновления к новой копии.
  • React проведет сравнение с использованием алгоритма сравнения между деревьями, найдет различия и объединит обновления в реальный DOM, проще говоря, заменит старые узлы новыми узлами.

Как обновляется виртуальный DOM?

  • Когда вы что-то меняете, виртуальный DOM сравнивается с реальным DOM перед любыми обновлениями на странице.
  • React определит, какие объекты изменились.
  • Только измененные объекты обновляются в реальном DOM.
  • Изменения в реальном DOM вызывают изменение экрана.
  • Когда вы пытаетесь обновить DOM в React, обновляется весь виртуальный DOM.

Преимущество виртуального DOM

  • Он не перерисовывает весь DOM, а только измененные узлы.
  • Это не приводит к падению производительности
  • Обновление виртуального DOM сравнительно быстрее, чем обновление фактического DOM (манипулирование реальным DOM очень дорого).

Плюсы реакции

  • Легко учиться - › Сильная поддержка сообщества
  • Компонентная структура -> Возможность повторного использования
  • VirtualDOM -> избегайте ненужного повторного рендеринга, манипулирование реальным DOM очень дорого
  • Алгоритмы различий (выводит набор различий между двумя входными данными) -> согласование («виртуальное» представление пользовательского интерфейса хранится в памяти и синхронизируется с «реальным» DOM с помощью такой библиотеки, как ReactDOM)
  • JSX (HTML + JS) -> писать HTML внутри JavaScript, хорошо для разработчиков — теперь можно избежать эффективного переключения контекста
  • Сосредоточьтесь на представлении -> Пользовательские интерфейсы
  • хуки и жизненный цикл компонента -> позволяют нам контролировать, как наш компонент должен вести себя в течение своего жизненного цикла, используя различные хуки.

Какие проблемы решает React?

  • улучшенная обработка динамических данных для более быстрого отклика
  • и мгновенная реакция на изменение данных
  • визуализирует правильные компоненты для удобного взаимодействия с пользователем.

оказывать()

  • он отображает HTML-элементы, содержащиеся в компоненте, в DOM.

состояние

  • state — это объект, который содержит данные, находящиеся внутри текущего компонента в виде локальных переменных или переменных экземпляра.
  • состояние — это данные, которые вы можете изменить внутри компонента, чтобы затем принудительно переоценить этот компонент.
  • это объект, внутренне захваченный классом (в конструкторе this.state)
  • объект, управляющий поведением компонента, может изменяться в течение времени жизни компонента.

государственная цель

  • Он используется для рендеринга данных в DOM.
  • Он используется для передачи в качестве реквизита дочернему компоненту.
  • Используется для интеграции с методом или функцией

реквизит

  • реквизиты — это данные, которые вы передаете от родительского компонента к дочернему компоненту.
  • реквизит вниз, родитель разговаривает с ребенком
  • Может ли ребенок возражать родителю, используя реквизит? НЕТ -› использование обратного вызова

супер (реквизит)

  • конструктор(реквизит) -> инициализировать состояние объекта в классе, вызываемом до его монтирования
  • super(props) -> вызвать конструктор родительского класса() компонента React в качестве ссылки

Подъем состояния вверх

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

Поднятие состояния против композиции против наследования

  • Подъем состояния: позволяет дочерним компонентам лучше общаться друг с другом.
  • Состав: {props.children} — передается как дочерние свойства, содержит любые дочерние элементы, определенные в компоненте.
  • Наследование: не лучшая модель для использования в React

Какие побочные эффекты?

  • Побочные эффекты — это в основном все, что влияет на что-то, выходящее за рамки текущей выполняемой функции.
  • Пример: запросы API к нашему серверному сервису.

Как вы синхронизируете эффекты в компоненте React с изменениями в определенных состояниях или свойствах?

  • во-первых, мы сохраняем состояния/реквизиты в родительском компоненте, то есть в том компоненте, где мы запускаем событие onClick; затем, чтобы передать состояние другому компоненту, мы просто передаем его как свойство.
  • useEffect вызывается после того, как React уже фиксирует обновления, т. е. обновления будут отражены в DOM; затем вы обновите состояние, которое снова обновит DOM. Второй способ вызывает повторный рендеринг, но коммит в DOM только один.
useEffect(() => {
  // Called on first render and every props.foo update
}, [props.foo])

Функциональный компонент

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

Компонент с состоянием против компонента без состояния

  • компоненты с отслеживанием состояния отслеживают изменение данных
  • компоненты без состояния всегда отображают одно и то же, распечатывают то, что им дается через реквизиты

Элемент против компонентов в React

  • React Element похож на HTML-элемент, неизменный объект, описывающий DOM-узел, к нему нельзя применять какие-либо методы.
  • Компонент React — это функция или класс, который принимает ввод и возвращает элемент React.

Списки и ключи

  • ключ помогает React определить, какие элементы были изменены (добавлены/удалены/переупорядочены) для отображения
  • дать уникальный идентификатор каждому элементу внутри массива, требуется ключ.
  • ключ — это уникальный элемент для перебора подкомпонентов, всегда добавляйте ключ на уровень выше!
  • { this.state.numArr.map((num, index) => ( <Child key={index} num={num} /> ))}

Ключ, не использующий индексы

  • не рекомендуется использовать индексы для ключей, особенно порядок элементов может измениться — плохой дизайн.
  • Если ключ является индексом, изменение порядка элемента изменяет его.
  • Состояние компонента может быть перепутано и может использовать старый ключ для другого экземпляра компонента.
  • Кроме того, итерация по списку, когда он большой, приводит к снижению производительности.
  • [a:0, b:1, c:2] -> [d:0, a:1, b:2, c:3] - плохо
  • [d:unique key, a:unique key, b:unique key] - хорошо

Атрибуты

  • defaultChecked - устанавливает, проверяется ли компонент при первом монтировании в <input>
  • dangerouslySetInnerHTML – Способ замены React для использования innerHTML в DOM браузера является рискованным, поскольку легко непреднамеренно подвергнуть ваших пользователей атаке с использованием межсайтового скриптинга (XSS) – <div dangerouslySetInnerHTML={__html: description} />
  • className, onChange, htmlFor, selected, value, style, tabIndex, readOnly

создатьПортал()

  • визуализировать дочерние элементы в узел DOM, ведет себя как обычный дочерний элемент React, но также включает всплытие событий, поскольку в дереве DOM
  • создание модальных окон, диалогов, всплывающих подсказок и всплывающих подсказок. с порталами вы можете отображать параллельное дерево реакций на другой узел DOM, когда это необходимо.
  • ReactDOM.createPortal(child {any renderable React child}, container {a DOM element})

Синтетическое событие

  • вся оболочка над системой событий DOM может иметь большой вес в кодовой базе React, не используя addEventListener браузера для внутренней обработки событий
  • потому что мы запускаем React в разных средах, поэтому нам нужна согласованность в нескольких браузерах, например, в оболочке.
  • согласованность -> обертка (basicEvent) => кросс-браузерная оболочка вокруг собственного события браузера

Реагировать. Фрагмент

  • выглядит чище, избегайте слишком большого количества <div>
  • <React.Fragment>...</React.Fragment>

Соглашение об именовании

  • [Domain]|[Page/Context]|ComponentName|[Type]
  • Домен: какому продукту принадлежит этот компонент?
  • Страница или контекст: что является родительским компонентом? к какой части/странице продукта относится этот компонент?
  • Компонент: что делает этот компонент? например боковая панель, короткий список, чат
  • Типы компонентов: вид, кнопка, подключение, ввод, загрузка

Рендеринг

Повторно отображает ситуации

  • Родительский компонент выполняет повторный рендеринг, в результате чего все дочерние элементы родителя пытаются выполнить повторный рендеринг, даже если реквизиты родителя не изменились.
  • Компонент вызывает this.setState(), что вызывает обновление состояния и повторную визуализацию.
  • Компонент вызывает this.forceUpdate(), что вызывает повторный рендеринг.
  • Замена компонента? Рендеринг. Родитель изменился? Рендеринг. Раздел реквизита, который на самом деле не влияет на вид, изменился? Рендеринг.

Что делает setState?

  • setState вызовет повторный рендеринг и правильно обновит/изменит локальное состояние.
  • когда используется предыдущее значение, мы всегда должны использовать функцию обратного вызова, чтобы правильно обрабатывать его на основе текущего значения.
this.setState((prevState) => {     //passing in a callback function instead of setState directly
  return { number: prevState.number + 1 };
})

Зачем нам обратный звонок?

  • useState и setState являются асинхронными.
  • Они не обновляют состояние немедленно, но имеют очереди, которые используются для обновления объекта состояния.
  • Используйте функцию обратного вызова для setState, чтобы он правильно отображал предыдущее значение, а не просто присваивал новый объект.
  • React объединит несколько setState в одно обновление для выполнения изменения состояния из-за производительности рендеринга компонентов React.

setState() за кулисами

  • setState являются асинхронными и группируются для повышения производительности —> реагировать на волокно —> затем рендерить
  • волокно: согласование, алгоритмы сравнения — выводит набор различий между двумя входными данными —> нет нового ключа, нет изменений в виртуальном DOM, улучшается производительность сети.
  • Пакетная обработка: React группирует несколько обновлений состояния в один повторный рендеринг для повышения производительности.
  • используя setState для изменения переменной внутри любой функции, вместо того, чтобы выполнять рендеринг в каждом setState, React собирает все setState, а затем выполняет их вместе.
  • независимо от того, сколько вызовов setState вы делаете внутри обработчика событий React или синхронного метода жизненного цикла, они будут объединены в одно обновление.

Пользовательский интерфейс материала

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

CSS-модуль

  • import styles from "./Button.module.css"; - импортировать модули CSS, также изменить имя файла CSS
  • <button type={props.type} className={styles.button} onClick={props.onClick}>

Стилизованные компоненты

  • пакет, помогающий создавать компоненты, к которым прикреплены определенные стили (CSS-in-JS)
import styled from "styled-components";
export const Button = styled.button`color: white;`	//using tagged template literal

Контролируемый компонент против неконтролируемого компонента

Контролируемый компонент

  • Данные обрабатываются компонентом React ‹-› значение ввода всегда управляется состоянием React
  • Изменение состояния имеет связанную функцию-обработчик, управляющую собственным состоянием и передающую новые значения в качестве реквизита контролируемому компоненту.
  • принимает свое текущее значение через свойства, а родительский компонент «управляет» им, обрабатывая обратные вызовы, такие как onChange.
  • рекомендуем использовать контролируемые компоненты для реализации форм
  • компонент, который отображает элементы формы и управляет ими, сохраняя данные формы в состоянии компонента.
  • <ControlledComp value={this.props.fromParent} onChange={this.props.handleChange} />
const { useState } from 'react';
function Controlled () {
  const [email, setEmail] = useState();
  const handleInput = (e) => setEmail(e.target.value);
  return <input type="text" value={email} onChange={handleInput} />;
}

Неконтролируемый компонент

  • Данные обрабатываются самой DOM.
  • немного больше похож на традиционный HTML, сохраняет единственный источник правды в DOM,
  • вы запрашиваете DOM, используя ref, чтобы найти его текущее значение, когда вам это нужно.
  • Рефы предоставляют способ доступа к узлам DOM или элементам React, созданным в методе рендеринга.
import React, { Component } from 'react';
export class App2 extends Component {
    constructor(props){
        super(props);
        this.handleChange = this.handleChange.bind(this);
        this.input = React.createRef();	//access the input DOM node and extract its value
    }
    handleChange = (newText) => {
        console.log(newText);
    }
    render() {
        return (
          <div className="App2">
	    <input type="text"
		ref={this.input}
		onChange={(event) => this.handleChange(event.target.value)}
	    />
          </div>    
        );
    }
}

HOC

HOC -> компонент высокого порядка

  • HOC — это шаблон, в котором функция принимает компонент в качестве аргумента и возвращает новый компонент в соответствии с определенным логическим шаблоном повторного использования компонента.
  • возьмите исходный компонент и добавьте некоторые украшения и модификации, а также реквизит, чтобы сделать его новым компонентом, добавьте больше содержимого
  • пример: подключение в React-Redux connect(a, b)(OriginalComp)

Почему ХОК?

  • используйте его для повторного использования, чтобы разделить общие функции между компонентами
  • тот же шаблон, но применяется только к тому, когда он нам нужен, и просто удаляем его, когда он нам не нужен

Пример HOC

import React from "react";
const UpdatedComponent = (OriginalComponent) => {
  class NewComponent extends React.Component{
    render() {
      return <OriginalComponent name="inject props"/>
    }
  }
  return NewComponent
}
export default UpdatedComponent;
import ContentContainer from "../HOC/ContentContainer";
const HOCCounter = UpdatedComponent(Counter);
export default HOCCounter;

Маршрутизатор

Что такое React Router?

  • Отличный способ создания одностраничных приложений, поскольку вы предотвращаете обновление страницы при каждом нажатии ссылки.
  • При рендеринге на стороне клиента страница не обновляется при переходе по различным ссылкам.
  • Несколько страниц в одностраничном приложении, изменения URL, изменения видимого содержимого.

Традиционная многостраничная маршрутизация

  • HTML запрашивается и загружается; Изменение страницы = новый запрос + ответ (рендеринг на стороне сервера).

Одностраничное приложение

  • Только один начальный HTML-запрос и ответ, изменения страницы (URL) затем обрабатываются кодом на стороне клиента (React) -> изменяет видимое содержимое без загрузки нового HTML-файла (рендеринг на стороне клиента).
  • Цель состоит в том, чтобы мы могли обрабатывать разные пути на нашей странице и загружать (рендерить) разные компоненты для разных путей.

Ссылка против маршрута

  • Компонент Link отвечает за переход из состояния в состояние (страница на страницу)
  • Компонент маршрута отвечает за то, чтобы действовать как переключатель для отображения определенных компонентов в зависимости от состояния маршрута.

использоватьпараметры()

  • Возвращает объект параметров для отображаемого маршрута.
// route: /user/:userName
const params = useParams();
return <h1>{params.userName}</h1>

использоватьRouteMatch();

  • пытается сопоставить текущий URL
let match = useRouteMatch();
<Link to={`${match.url}/components`}>Components</Link>
<Route path={`${match.path}/:topicId`}>

Реализация маршрутизатора React

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
} from "react-router-dom";
export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
        </ul>
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

Жизненный цикл

Компонент класса против функционального компонента

  • мы используем компонент класса, когда компонент имеет собственное локальное состояние и жизненный цикл до React 16.8.
  • теперь мы можем использовать хуки реагирования для выполнения локального состояния и жизненного цикла в функциональном компоненте

Эффекты жизненного цикла

  • Функции запускают код, когда компонент создается, обновляется или удаляется со страницы.

Жизненный цикл (3 фазы) — монтирование, обновление, размонтирование

  • Монтаж (constructor() и render()): конструктор инициализации -> присваивает начальное this.state, а компоненты рендеринга —> у нас есть поверх начального рендера в DOM
  • componentDidmount (начальный рендер) -> только после начального рендера мы вызываем componentDidMount
  • Обновление: когда компонент обновляется в результате изменения состояния или изменения свойств.
  • componentDidUpdate (обновление) -> когда мы обновляем, нам нужно изменить какое-то состояние, чтобы вызвать повторный рендеринг
  • Размонтирование: когда компонент удаляется из DOM.
  • componentWillUnmount -> правильная очистка для предотвращения утечки памяти (удалить eventListener, удалить setTimeout)

использоватьЭффект()

  • принимает два параметра, 1-й — функция обратного вызова, 2-й — массив зависимостей
  • возвращаемая функция будет вызываться после удаления компонента
  • мы можем сделать очистку в возвращаемой функции
function XXX () {
  const [name, setName] = useState("");
  useEffect(() => {
	console.log("This is component did mount");
	
	return () => {
	  console.log("This is component did unmount");
	  console.log("returned function will be called on componentWillUnmount, for clean up, uunmount first then updates");
	}
  }, [])	//no dependencies here, so only the first render
  
  useEffect(() => {
	console.log("This is component did update");
  }, [name])	//will be called whenever the dependency updates
  
  return <p>This is render.</p>
}

React.PureComponent против памятки

  • Та же функциональность, оба предназначены для повышения производительности, React.memo — это компонент более высокого порядка — оболочка.
  • С PureComponent или memo он уже содержит логику shouldComponentUpdate — сравнивает пропсы
  • Чтобы сравнить текущие реквизиты и предыдущие реквизиты, чтобы убедиться, что они отсекают ненужные рендеры.

Неглубокое сравнение — React.memo()

  • React.memo() выполняет поверхностное сравнение реквизита и объектов реквизита.
  • В JavaScript поверхностное сравнение объектов всегда будет возвращать false, даже если они имеют одинаковые значения.
  • Если вам нужен больший контроль и ответственность за это сравнение, React.memo принимает второй аргумент — функцию сравнения.

Граница ошибки

  • только компонент класса, определите один или оба метода жизненного цикла getDerivedStateFromError (рендеринг резервного пользовательского интерфейса после возникновения ошибки) и componentDidCatch (регистрация информации об ошибке)
  • ловить ошибки JS в дочернем дереве компонентов, регистрировать эти ошибки и отображать резервный пользовательский интерфейс
  • отсутствие границ ошибок в обработчике событий, асинхронные коды, рендеринг на стороне сервера, ошибки, выбрасываемые сами по себе, чем дочерние элементы

Граница ошибки vs Try…Catch…

  • Try…catch имеет дело с императивным кодом: как вы что-то делаете, вы можете отлавливать ошибки в своем коде.
  • Границы ошибок связаны с декларативным кодом: то, что вы делаете, например, в случае ошибки, вы можете вызвать резервный пользовательский интерфейс.

Крючки

Что такое хуки?

  • Хуки — это функции, которые позволяют вам «подключаться» к функциям состояния и жизненного цикла React из функциональных компонентов.
  • Хуки не работают внутри компонентов класса. Вы также можете создавать свои собственные хуки для повторного использования поведения с отслеживанием состояния между различными компонентами.

использовать состояние()

  • const [state, setState] = useState(initialState) - функция значения и установки
const computationInit = () => return 0;
function App() {
  const [count, setCount] = useState(() => computationInit()); //callback function, only called at the initial time
  const [name, setName] = useState(""); //another local state, initial state in ()
  return (
    <>
      <button onClick={() => setCount(count + 1)}>+</button>
      <div>Count Number {count}</div>
      <button onClick={() => setName("Hello")}>show name</button>
      <div>{name}</div>
    </>
  );
}
export default App;

function App() {
  const [{ count1, count2 }, setCount] = useState({ count1: 1, count2: 2 });
  return (
    <>
      <button
        onClick={() =>
          setCount((prevState) => {	//without ...prevState, it overwrites the object
            return {
              ...prevState,	//...prevState first - give all the key I have then make modification to the count1
              count1: prevState.count1 + 1 //we only modify count1 without changing/overriding count2
            };
          })
        }
      >
        +
      </button>
      <div>Count 1 - {count1}</div>
      <div>Count 2 - {count2}</div>
    </>
  );
}

использоватьЭффект()

  • создать побочный эффект, когда что-то происходит или меняются зависимости: «Если какая-то переменная изменится, сделайте это».
  • useEffect запускается после анализа DOM из-за асинхронного характера JS.
  • useEffect(...,[]): componentDidMount() — вызывается после монтирования компонента (оценка и визуализация)
  • useEffect(..., [someValue]): componentDidUpdate() — вызывается после обновления компонента (был оценен и отрендерен)
  • useEffect(() => {return () => {...}}, []): componentWillUnmount() - вызывается непосредственно перед размонтированием компонента (удалением из DOM)
function XXX () {
  const [name, setName] = useState("");
  
  useEffect(() => {
	console.log("This is component did mount");
	return () => {
	  console.log("This is component did unmount")'
	}
  }, [])  //empty array -> ComponentDidMount (no dependency, we call it after every render)
  	//with dependencies in the array, will be called when the value changes
  
  useEffect(() => {
	console.log("This is component did update");
  })
 
  return <p>This is render.</p>
}

useEffect() + Аксиос

  • В useEffect сделайте запрос, есть ли сетевая ошибка или нет, и установите тайм-аут, чтобы время выборки не было бесконечным.
React.useEffect(() => {
    (async () => {
      try {
        const result = await Axios.get(
          "http://media.xiph.org/mango/tears_of_steel_1080p.webm",
          { timeout: 5000}
        );
        // Do something here
      } catch (e) {
        console.log("The link is not avaible", e.message);
        // Do something here
      }
    })();
  }, []);

использоватьСсылка()

  • запросите DOM, используя ref, чтобы найти его текущее значение, когда вам это нужно (используйте ref для ссылки на элементы внутри вашего HTML)
  • ref сохраняет значение постоянным, но не вызывает повторного обновления вашего компонента при его изменении, тогда как setState запускает повторный рендеринг
  • когда вам нужно изменить какое-либо значение, по-прежнему используйте setState()
const [name, setName] = useState('')
const inputRef = useRef()
const prevName = useRef('')
function focus(){
  inputRef.current.focus()	//inputRef.current refers to <input value>
}
if (name === inputRef.current.value) {
}
useEffect(() => {
  prevName.current = name
}, [name])
return (
  <>
    <input ref={inputRef} value={name} onChange={e => setName(e.target.value)}/>
    <div>My name is {name}, used to be {prevName.current}. </div>
    <button onClick={focus}>Focus</button>
  </>
  )
}

использоватьконтекст()

  • указать определенные фрагменты данных, которые будут доступны всем компонентам, вложенным в контекст, без необходимости передавать эти данные через каждый компонент
  • export const ThemeContext = React.createContext() инициировать контекст, значения по умолчанию, фактически не используемые, но для автозаполнения
  • const [darkTheme, setDarkTheme] = useState(true)
  • <ThemeContext.Provider value={darkTheme}>{everything has the access to the value props}</ThemeContext.Provider>
  • класс: <ThemeContext.Consumer>{value is available to the component}</ThemeContext.Consumer>
  • function: const darkTheme = useContext(ThemeContext) - тогда darkTheme доступна для использования в компоненте

использоватьредусер()

  • обработка сложного управления взаимодействием состояний, альтернатива useState
  • редуктор принимает 2 параметра, функцию и начальное значение и возвращает одно значение
  • function reducer(state, action) { return {} } - обычно переключаются случаи с action.type, который отправляется редюсеру для изменений
  • const [state, dispatch] = useReducer(reducer, initialState) - InitialState всегда имеет объекты типа [] {count:0}
  • function increment() { dispatch({ type: "increment" }) } - отправить тип действия редюсеру
const ingredientReducer = (currentIngredients, action) => {
  switch (action.type) {
    case 'SET':
      return action.ingredients;
    case 'ADD':
      return [...currentIngredients, action.ingredient];
    case 'DELETE':
      return currentIngredients.filter(ing => ing.id !== action.id);
    default:
      throw new Error('Should not get there!');
  }
};
const httpReducer = (curHttpState, action) => {
  switch (action.type) {
    case 'SEND':
      return { loading: true, error: null };
    case 'RESPONSE':
      return { ...curHttpState, loading: false };
    case 'ERROR':
      return { loading: false, error: action.errorMessage };
    case 'CLEAR':
      return { ...curHttpState, error: null };
    default:
      throw new Error('Should not be reached!');
  }
};
const [userIngredients, dispatch] = useReducer(ingredientReducer, []);
const [httpState, dispatchHttp] = useReducer(httpReducer, { loading: false, error: null });
const filteredIngredientsHandler = useCallback(filteredIngredients => {
    dispatch({ type: 'SET', ingredients: filteredIngredients });
    dispatchHttp({ type: 'SEND' });
    dispatchHttp({ type: 'RESPONSE' });
    dispatch({ type: 'DELETE', id: ingredientId });
  }, []);
const clearError = () => {
    dispatchHttp({ type: 'CLEAR' });
  };

Производительность реакции — useMemo() и useCallback()

  • как для предотвращения ненужных повторных рендеров, так и для повышения эффективности вашего кода.
  • кэшировать функцию в функциональном компоненте с массивом зависимостей

.useCallback() - запомнить актуальную функцию

  • избегая ненужных рендеров от дочернего элемента, меняйте ссылку только при изменении зависимостей
  • используйте его, когда функция зависит от побочного эффекта
  • сохранить функцию, которая не изменяется, чтобы не генерировалась новая функция
  • точно так же, как useMemo, не будет повторно запускать код внутри него, если не будет изменен определенный параметр
  • возьмите функцию, которая возвращается useCallback, сохраняет ее в переменной, а позже вы можете использовать ее как getItems(1)
  • Возвращает запомненный обратный вызов. useCallback запомнит вашу фактическую функцию.
const getItems = useCallback((incrementor) => {	//return us the entire function
  return [number + incrementor, number + incrementor + 1, number + incrementor + 2]
}, [number])

.useMemo() - запомнить значение из функции

  • запускаться при каждом рендеринге, но с кэшированными значениями, будут использовать новые значения только при изменении определенных зависимостей.
  • useMemo принимает два аргумента: функцию и список зависимостей, каждый раз, когда useMemo сначала проверяет, изменились ли какие-либо зависимости
  • Если нет, он вернет кэшированное возвращаемое значение, не вызывая функцию. (запоминать, кэшировать, не нужно пересчитывать)
  • Если они изменились, useMemo снова вызовет предоставленную функцию и повторит процесс.
  • Возвращает запомненное значение. useMemo запомнит возвращаемое значение из вашей функции.
const doubleNumber = useMemo(() => {	//only return the value of the function
  return slowerFunction(number)
}, [number])

Контекст

Что такое React-контекст?

  • Контекст предоставляет способ передачи данных через дерево компонентов без необходимости вручную передавать реквизиты на каждом уровне.
  • С помощью контекста мы можем напрямую получить значение для вложенных дочерних элементов.
  • Без Redux и React Context нам нужно поднимать состояние вверх.

Как использовать контекст

  • export const Context = React.createContext() - инициировать контекст и значения по умолчанию, не используемые на самом деле, а для автозаполнения
  • класс: Использование < Context.Provider value={} > и < Context.Consumer > для переноса кода возврата
  • функция: использование < Context.Provider value={} > и использование хука useContext, затем const value = useContext(Context)

Реагировать против Редукса

  • У вас может быть несколько контекстов, но только одно хранилище в Redux.
  • Если вы используете React Context, это может привести к загрязнению данных, поскольку потребитель ищет ближайшего предка поставщика.
  • defaultValue ‹=› всплывающее — всегда поднимайтесь, чтобы посмотреть на ближайшую родословную
  • В контексте GrandChild.js — ищите дочернее значение, но не родительское.
  • мы можем ошибаться или не сможем получить желаемое значение, так как значение передается в GrandChild, ближайшим предком является Child

Когда будет здорово использовать Context?

  • Redux — более масштабное приложение
  • Контекст — Приложение меньшего масштаба

Недостатки по сравнению с Redux

  • сложная настройка/управление может привести к глубоко вложенному коду JSX и/или огромному компоненту поставщика контекста
  • производительность, контекст реакции не оптимизирован для высокочастотных изменений состояния

Чтобы узнать больше о Redux, нажмите здесь