
Size: a a a





componentDidMount и useEffect в одной картинкеcomponentDidMount всегда вызывается в текущем кадре, а useEffect — обычно в начале следующего)
componentDidMount это вызовет принудительное перевычисление стилей (это дорого). А в useEffect не вызовет — браузер к тому моменту уже завершит кадр и перевычислит всё сам.useLayoutEffect вызывается там же, где и componentDidMount — в текущем кадре. Из-за этого код в useLayoutEffect тоже может вызвать принудительное перевычисление. Это главная причина, по которой React не рекомендует использовать useLayoutEffect (если вы только не знаете наверняка, зачем он вам).useEffect обычно вызывается в следующем кадре — но не всегда. Если у React запланировано несколько рендеров подряд, он будет вызывать useEffect сразу перед следующим рендером, не дожидаясь окончания кадра. См. документацию → «it’s guaranteed to fire before any new renders»

/* pages/my-page.js */export const config = {
unstable_runtimeJS: false
}
export default () => <h1>My page</h1>
const userId = useSelector(state => state.selectedUser.id)useSelector вызывает перерисовку компонента каждый раз, когда данные меняются. Это полезно — если пользователь поменялся, мы хотим, чтобы и его аватарка перерисовалась:
userId не в самом компоненте, а в обработчике события? Тогда компонент будет перерисовываться зря. userId будет меняться, но DOM будет оставаться таким же:
<ChangeUserAvatarButton /> дорогой, а выбранный пользователь меняется часто, это может быть проблемой. useSelector без проблем заменяется на useStore:
useStore вернёт стор — и всё. Он не будет извлекать какие-то конкретные поля из стора. Он не будет перерисовывать компонент, когда что-то меняется.userId прямо из store.getState(). Никаких лишних ререндеров.










<link rel="stylesheet"> загрузились, можно отрендерить страницу». А Typekit ему такой: «пха, погоди, у меня тут ещё одни стили, не хочешь и их загрузить сначала?» И всё — вместо того, чтобы загрузить всё за раз, браузер загружает новые стили по второму кругу.