https://ru.reactjs.org/docs/react-component.html
вызывается сразу после монтирования (то есть, вставки компонента в DOM). В этом методе должны происходить действия, которые требуют наличия DOM-узлов. Это хорошее место для создания сетевых запросов.
вызывается сразу после обновления. Не вызывается при первом рендере.
вызывается непосредственно перед размонтированием и удалением компонента. В этом методе выполняется необходимый сброс: отмена таймеров, сетевых запросов и подписок, созданных в componentDidMount().
Хук эффекта даёт вам возможность выполнять побочные эффекты в функциональном компоненте:
useEffect(() => {
});Пустой набор зависимостей [] означает, что эффект будет выполняться только один раз, когда компонент монтируется, а не при каждом повторном рендере.
useEffect(() => {
}, []);useEffect(() => {
const interval = setInterval(() => {
setTime(new Date());
}, 1000);
return () => clearInterval(interval);
});useEffect(() => {
document.title = `Вы нажали ${count} раз`;
}, [count]); // Перезапускать эффект только если count поменялсяВозвращает значение с состоянием и функцию для его обновления.
const [state, setState] = useState(initialState);
const [count, setCount] = useState(initialState);Во время первоначального рендеринга возвращаемое состояние (state) совпадает со значением, переданным в качестве первого аргумента (initialState).
Функция setState используется для обновления состояния. Она принимает новое значение состояния и ставит в очередь повторный рендер компонента.
setState(newState);Во время последующих повторных рендеров первое значение, возвращаемое useState, всегда будет самым последним состоянием после применения обновлений.
setCount(prevCount => prevCount - 1)}
setState(prevState => {
return {...prevState, ...updatedValues};
});значения переданные в useState будет применено только один раз при вкл. жизненного цикла в первый рендер
вычисление этого значения может быть достаточной дорогой и тяжелой операцией, а вычисляться оно будет каждый рендер как и все остальные выражения в коде функции компонента
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
});Чистая функция, возвращает один и тот же результа при неизменных входных параметрах
Сайд эффект - все что изменяет результат функции с течением времени, или это взаимодействия функции с внешним миром(контекстом) по отношению к этой функции
const add = (a,b) => {
return a + b;
}let counter = 0
const add = (a,b) => {
counter++; //side effect
return a + b;
}Принимает функцию, которая содержит императивный код, возможно, с эффектами.
useEffect(() => {
}, [])- аргумент - это callback
- список зависимостей - своего рода список входящих параметров, в callback
Мутации, подписки, таймеры, логирование и другие побочные эффекты не допускаются внутри основного тела функционального компонента (называемого этапом рендеринга React). Это приведёт к запутанным ошибкам и несоответствиям в пользовательском интерфейсе.
Функция, переданная в useEffect, будет запущена после того, как рендер будет зафиксирован на экране.
По умолчанию эффекты запускаются после каждого завершённого рендеринга, но вы можете решить запускать их только при изменении определённых значений.
функция переданная в useEffect, может вернуть функцию очистки.
Функция очистки запускается до удаления компонента из пользовательского интерфейса, чтобы предотвратить утечки памяти. Кроме того, если компонент рендерится несколько раз (как обычно происходит), предыдущий эффект очищается перед выполнением следующего эффекта.
В отличие от componentDidMount и componentDidUpdate, функция, переданная в useEffect, запускается во время отложенного события после разметки и отрисовки. Это делает хук подходящим для многих распространённых побочных эффектов, таких как настройка подписок и обработчиков событий, потому что большинство типов работы не должны блокировать обновление экрана браузером.
useEffect(() => {
console.log('this click Heading')
}, [count]);Сигнатура идентична useEffect, но этот хук запускается синхронно после всех изменений DOM. Используйте его для чтения макета из DOM и синхронного повторного рендеринга. Обновления, запланированные внутри useLayoutEffect, будут полностью применены синхронно перед тем, как браузер получит шанс осуществить отрисовку.
если нужно устранить неконсистентное состояние
useRef возвращает изменяемый ref-объект, свойство .current которого инициализируется переданным аргументом (initialValue). Возвращённый объект будет сохраняться в течение всего времени жизни компонента.
const refContainer = useRef(initialValue);Имейте в виду, что useRef не уведомляет вас, когда изменяется его содержимое. Мутирование свойства .current не вызывает повторный рендер.
function getLogger(arg) {
function logger() {
console.log(arg)
}
return logger
}
let fruit = 'raspberry'
const logFruit = getLogger(fruit)
logFruit() // "raspberry"
fruit = 'peach'
logFruit() // "raspberry" Wait what!? Why is this not "peach"?function getLatestLogger(argRef) {
function logger() {
console.log(argRef.current)
}
return logger
}
const fruitRef = {current: 'raspberry'}
const latestLogger = getLatestLogger(fruitRef)
latestLogger() // "raspberry"
fruitRef.current = 'peach'
latestLogger() // "peach" 🎉Возвращает мемоизированный колбэк.
Хук useCallback вернёт мемоизированную версию колбэка, который изменяется только, если изменяются значения одной из зависимостей.
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);Возвращает мемоизированное значение.
Передайте «создающую» функцию и массив зависимостей. useMemo будет повторно вычислять мемоизированное значение только тогда, когда значение какой-либо из зависимостей изменилось. Эта оптимизация помогает избежать дорогостоящих вычислений при каждом рендере.
Помните, что функция, переданная useMemo, запускается во время рендеринга. Не делайте там ничего, что вы обычно не делаете во время рендеринга. Например, побочные эффекты принадлежат useEffect, а не useMemo.
Вы можете использовать useMemo как оптимизацию производительности, а не как семантическую гарантию.
Все объекты и массивы которые вы используите внутри компонента и передаете куда то пропсами, необходимо мемоизировать
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);const searchQuery = 'Mag'
const items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: 12 },
{ name: 'Magnetic', value: 5 },
{ name: 'Zeros', value: 37 }
];
const sort = () => {
return [...items].sort((a,b) => a.value - b.value);
}
const search = () => {
return sort().filter(item => item.name.includes(searchQuery))
}const searchQuery = 'Mag'
const items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: 12 },
{ name: 'Magnetic', value: 5 },
{ name: 'Zeros', value: 37 }
];
const sort = useMemo(() => {
return [...items].sort((a,b) => a.value - b.value);
}, [items])
const search = useMemo(() => {
return sort().filter(item => item.name.includes(searchQuery))
}, [searchQuery, sort])https://ru.reactjs.org/docs/react-api.html#reactmemo
React.memo — это компонент высшего порядка.
Если ваш компонент всегда рендерит одно и то же при неменяющихся пропсах, вы можете обернуть его в вызов React.memo для повышения производительности в некоторых случаях, мемоизируя тем самым результат. Это значит, что React будет использовать результат последнего рендера, избегая повторного рендеринга.
React.memo затрагивает только изменения пропсов. Если функциональный компонент обёрнут в React.memo и использует useState, useReducer или useContext, он будет повторно рендериться при изменении состояния или контекста.
https://ru.reactjs.org/docs/context.html
Контекст позволяет передавать значение глубоко в дерево компонентов без явной передачи пропсов на каждом уровне.
Обычно контекст используется, если необходимо обеспечить доступ данных во многих компонентах на разных уровнях вложенности. По возможности не используйте его, так как это усложняет повторное использование компонентов.
https://ru.reactjs.org/docs/context.html
https://beta.reactjs.org/learn/passing-data-deeply-with-context
https://habr.com/ru/company/ncloudtech/blog/685400/
практика передачи одного свойства на несколько уровней от родительского компонента к дочернему.
Решение:
- context
- композиция
- рендер-пропсы
- state management
https://habr.com/ru/company/alfa/blog/647013/
https://www.smashingmagazine.com/2021/08/compound-components-react/
https://beta.reactjs.org/learn/sharing-state-between-components
Compound components это подход, в котором вы объединяете несколько компонентов одной общей сущностью и общим состоянием. Отдельно от этой сущности вы их использовать не можете, тк они являются единым целым. Это как в BEM нельзя использовать E - элемент, отдельно от B - блока.
<select name="meals">
<option value="pizza">Pizza</option>
<option value="pasta">Pasta</option>
<option value="borsch">Borsch</option>
<option value="fries">Fries</option>
</select>
<Select>
<Option value="pizza" />
<Divider />
<Option value="pasta" />
<Option value="borsch" />
<Option value="fries" />
</Select>https://ru.reactjs.org/docs/render-props.html
https://ant.design/components/table/
Термин «рендер-проп» относится к возможности компонентов React разделять код между собой с помощью пропа, значение которого является функцией.
https://ru.reactjs.org/docs/composition-vs-inheritance.html
Компонент высшего порядка — это функция, которая принимает компонент и возвращает новый компонент.
HOC — это инструмент для параметризированного создания контейнеров.
const withHigherOrderComponent = (Component) => (props) =>
<Component {...props} />;https://www.patterns.dev/posts/hoc-pattern/
https://www.patterns.dev/posts/presentational-container-pattern/
https://ant.design/components/checkbox/
https://github.com/css-modules/css-modules
https://www.npmjs.com/package/classnames
https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
