Basics Flashcards
В чем заключается философия React?
React
предлагает свой способ мышления при создании приложений:
1. Интерфейс разбивается на составные части, компоненты
.
Каждый компонент должен соответствовать принципу SRP (принцип единственной ответственности)
.
Компонент должен быть разделен на составные компоненты, если его ответственность расширяется.
2. Составляется статическое приложение.
Написание кода идет от родительского компонента к дочернему, предусматривается передача данных в одностороннем порядке с помощью механизма передачи props
.
3. Определяются источники данных
и минимально необходимые состояния интерфейса.
4. Добавляются состояния
интерфейса в приложение.
Определенное состояние добавляется к определенным компонентам в зависимости от необходимости изменять данные в определенной части приложения.
5. Добавляется обратный поток данных.
К компонентам добавляются обработчики действий пользователя
для изменения состояния.
Что такое JSX?
JSX
- это надстройка над JavaScript, которая позволяет писать HTML-подобную разметку документа.
JSX компилируется в вызовы createElement
, который создает React-элемент:
createElement(type | Component, props, children) => ReactElement
React-элемент программно - это объект его описывающий.
В процессе отрисовки React-элемент преобразовывается в DOM-подобный-элемент в VirtualDOM
, затем этот элемент применяется к DOM
.
Что такое компонент?
Компонент - это функция
с параметрами-props
, которая возвращает React-элемент
.
Компонент может быть описан как функция или как класс:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; } class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
Как работает отрисовка в React?
Для создания базового элемента используется метод ReactDOM.createRoot(DOMElement)
, для отрисовки вызывается метод root.render(ReactElement | Component)
.
const root = ReactDOM.createRoot( document.getElementById('root') ); const element = <h1>Hello, world</h1>; root.render(element);
В процессе отрисовки происходит последовательный разбор дерева
React-элементов: вызов компонентов-функций или render-методов компонентов-классов до базовых элементов, после чего React применяет изменение DOM по всем найденным измененным базовым элементам
.
Чтобы изменить DOM-дерево, соответствующее компоненту, необходимо изменить состояние компонента
.
React не отрисовывает значения false
и null
.
Так как React незвестно, какие элементы должны заменить иные при изменении дерева, возможно подписать компонент или элемент уникальным значением на своем уровне с помощью props.key
.
При одних и тех же данных компонент всегда должен возвращать один и тот же JSX
.
Отрисовка может произойти в любой момент, поэтому компонент не должен изменять состояние при отрисовке JSX
.
Что такое состояние компонента?
У компонента может быть внутреннее состояние, которое позволяет логически отделить часть приложения от остальных.
Состояние сохраняется в экземпляре классового компонента:
~~~
class Clock extends React.Component {
constructor(props) {
super(props)
this.state = { date: new Date() }
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>Now: {this.state.date.toLocaleTimeString()}.</h2>
</div>
)
}
}
~~~
Состояние компонента-класса возможно изменить, используя метод this.setState(partialState | (prevState) => partialState, callback?)
, который принимает аргументом следующее значение состояния или коллбек в который передается предыдущее значение, и который возвращает новое состояние.
Переданное значение состояния поверхностно сливается с предыдущим.
Также состояние возможно добавить к компоненту-функции с помощью хуков useState(default) => [state, setState(nextSate | (prevState) => nextState)]
и useReducer
.
~~~
function Clock(props) {
const [date, setDate] = useState(new Date())
return (
<div>
<h1>Hello, world!</h1>
<h2>Now: {date.toLocaleTimeString()}.</h2>
</div>
)
}
~~~
Все изменения состояния выполняются группой последовательно и асинхронно, перерисовка происходит один раз.
Изменение состояния через setState(callback)
применяются перед следующей перерисовкой.
Что такое согласование’1?
‘1 Reconciliation
Согласование - это алгоритм сравнения узлов React для определения узлов DOM, нуждающихся в обновлении.
В своей основе он берет два утверждения:
1. Элементы с разными типами отрисовывают разные деревья.
2. Разработчик сам укажет узлы, которые должны оставаться стабильными с props.key
.
Порядок вызова методов для элементов различных типов:
1. Выполняется componentWillUnmount
или useEffect(() => onUnmount))
старого узла
2. Выполняется UNSAFE_componentWillMount
и componentDidMount
, или тело компонента-функции и useEffect(onMount) нового узла
Порядок вызова методов для элементов одного типа:
1. Выполняется UNSAFE_componentWillReceiveProps
старого узла
2. Выполняется UNSAFE_componentWillUpdate
и componentDidUpdate
, или тело компонента-функции и `useEffect(onUpdate, dep[])
Напишите пример компонента с примерами работы механизмов согласования.
Code Sandbox
sadff
import React, { useState, useEffect } from "react" import ReactDOM from "react-dom" function Comp({prop}) { useEffect(() => { console.log('mount', prop) return () => { console.log('unmount', prop) } }, []) return <div>{prop}</div> } function App() { const [state, setState] = useState(false) const onClick = () => { setState(!state) } return <> <div onClick={onClick}>change</div> {state ? <Comp prop="1" key="1" /> : <Comp prop="2" key="2" />} </> } const rootElement = document.getElementById("root") ReactDOM.render(<App />, rootElement)
Что такое render-prop?
Render-prop - это prop
-функция, которая возвращает React-элементы. Действует аналогично передаче props
-элементов, но в JSX компонента возможно вызвать эту функцию с аргументом из состояния компонента, чтобы получить React-элементы, с props
, соответствующими этому состоянию.
~~~
function Component({renderProp, prop1, prop2}) {
return <div>{renderProp(prop1, prop2)}</div>
}
…
const renderProp = (prop1, prop2) => prop1 ? <h1>{prop2}</h1> : <div>{prop2}</div>
const Element = <Component prop1={…} prop2={…} renderProp={renderProp} />
~~~
Что такое контекст?
Контекст - это способ передачи состояния в компоненты на любом уровне в дереве.
Контекст создается методом React.createContext(default) => ({Provider, Consumer})
с аргументом-значением по умолчанию, которое используется при отсутствии в дереве Provider
.
Контекст состоит из двух компонентов Provider
и Consumer
.Provider
передает значение props.value
в дочерние компоненты.Consumer
принимает состоние value
как аргумент в render-prop props.children
.
~~~
<Consumer>{(value) => <Component value={value} />}</ Consumer>
~~~
В компонентах-функциях применяется хук `useContext(Context) => value`.
Так как контекст передает состояние, то все компоненты-потребители перерисовываются при его изменении.
</Consumer>
Что такое ref?
Ref- это объект, который прикрепляется к экземпляру компонента и способен хранить текущее значение в свойстве ref.current
независимо от перерисовок.
Создать ref возможно с помощью метода React.createRef() => ref
и хранить в экземпляре this.someRef
компонента-класса, или с помощью хука useRef(default) => ref
в компоненте-функции.
Передача ref в элементы и компоненты:
1. Если передать ref в props.ref
React-элемента, то React будет обновлять свойство ref.current
ссылкой на соответствующий DOM-элемент при монтировании и очищать его при размонтировании.
2. Если в props.ref
React-элемента передать коллбек, то React будет вызывать этот коллбек при каждом монтировании и размонтировании.
3. Если передать ref в props.ref
компонента-класса, то возможно получить ссылку экземпляр компонента. Аналогичное поведение возможно создать с применением хука useImperativeHandle(ref, callback, deps?)
.
4. Если передать ref в компонент-функцию, обернутую в React.forwardRef(ref, Component)
, возможно перенаправить ref на любой внутренний элемент в JSX.
Что такое портал?
Портал - это компонент, который способен отрисовывать React-элемент в назначенном DOM-элементе.
Чтобы создать портал, используется метод ReactDOM.createPortal(ReactElement, DOMElement)
с аргументами React-элементом и DOM-элементом.
Синтетические события всплывают через порталы.
Что такое фрагмент?
Фрагмент - это компонент, который логически объединяет однородные элементы в один элемент, но не отрисовывается в DOM. Запись <>{elements}</>
аналогична <React.Fragment>{elements}</ React.Fragment>
.
Как работают формы в React?
По умолчанию React интерпретирует React-элементы формы (input, textarea, select, option) как компоненты со своим состоянием, которое соответствует значению в DOM-элементе, такие элементы называются неуправляемыми. Для передачи исходного значения возможно применение props.defaultValue
и props.defaultChecked
.
Если передать значение props.value
или props.checked
, то компонент считается управлемым и не хранит состояние.
Как работают события в React?
React поддерживает возможность передачи обработчиков событий в DOM-элементы через props.on*
для обработки событий, создаваемых пользователем.
Событие в React - это “синтетическое событие”, обертка над нативным событием браузера, для нормализации поведения между разными агентами.
Композиция или наследование?
В ряде случаев при использовании компонентов-классов необходимо применить наследование, когда требуется вмешаться с логику работы компонента при отсутствии доступа к его коду.
В остальных случаях рекомендуется использовать композицию, когда компоненты расширяют функциональность через оборачивание в компоненты.