20.1 React
Создание проекта
npm create vite@latest
npm i
npm run dev
Компоненты
React позволяет проще строить интерфейсы с помощью компонентов
Компонент это функция, которая возвращает JSX
JSX это синтаксический сахар, который React преобразует в JS
Компоненты могут содержать состояние
Плюсы компонентов
Переиспользуемость
Разделение ответственность
Удобное тестирование
Props
Props предназначен для передачи данных между компонентами
Это позволяет эффективно переиспользовать компоненты
import JournalItem from "./JournalItem" ;
function App () {
const data = [
{
title : "Подготовка обновления курсов" ,
date : new Date (),
text : "Горные походы открывают удвительные природные ландшафты" ,
},
{
title : "Подготовка обновления курсов2" ,
date : new Date (),
text : "Горные походы 222 открывают удвительные природные ландшафты" ,
},
];
return (
<>
< JournalItem
title = { data [ 0 ]. title }
text = { data [ 0 ]. text }
date = { data [ 0 ]. date }
/>
</>
);
}
function JournalItem ({ title , text , date }) {
const formatedDate = new Intl . DateTimeFormat ( "ru-RU" ). format ( date );
return (
< div className = "journal-item" >
< h2 className = "journal-item__header" >{ title }</ h2 >
< h2 className = "journal-item__body" >
< div className = "journal-item__date" >{ formatedDate }</ div >
< div className = "journal-item__text" >{ text }</ div >
</ h2 >
</ div >
);
}
export default JournalItem ;
Обработка событий
function Button ({ children , onClick }) {
console . log ( 'Button' );
return (
< button className = 'button accent' onClick = { onClick }>{ children }</ button >
);
}
useState
Это функция которая возвращает кортеж состояния и функцию для обновления состояния
Значение меняется на сразу, а будет запланировано к изменению react'ом
При повторном рендиренге useState не будет присваивать дефолтное значение
const [ text , setText ] = useState ( "Save" );
// Для использования текущего "старого состояния"
setText ( oldText => oldText + "!" );
useReducer
useReducer() это альтернатива useState() которая дает больший контроль над управлением состояния и упрощает тестирование
Все примеры можно реализовать и с помощью useState()
function reducer ( state , action ) {
switch ( action . type ) {
case 'ADD' : return { count : state . count + 1 };
case 'SUB' : return { count : state . count - 1 };
default : return state ;
}
}
function Counter () {
const [ state , dispatch ] = React . useReducer ( reducer , { count : 0 });
return (
<>
Итого : { state . count }
< button onClick = {() => dispatch ({ type : 'ADD' })}> Добавить </ button >
< button onClick = {() => dispatch ({ type : 'SUB' })}> Вычесть </ button >
</>
);
}
useContext
Обычно контекст используется, если необходимо обеспечить доступ данных во многих компонентах на разных уровнях вложенности.
По возможности не используйте его, так как это усложняет повторное использование компонентов.
Чтобы определить данные, которые мы хотим отправлять, мы должны начать с поставщика контекста ( ).
Затем определяется потребитель контекста ( ), который захватывает эти данные и использует их там, где они вызываются.
const { userId } = UserContext ( UserContext );
Простая декомпозиция на компоненты
Работа с формами
Работа со списком данных
function App () {
const data = [
{
id : 1 ,
title : "Подготовка обновления курсов" ,
date : new Date (),
text : "Горные походы открывают удвительные природные ландшафты" ,
},
{
id : 2 ,
title : "Подготовка обновления курсов2" ,
date : new Date (),
text : "Горные походы 222 открывают удвительные природные ландшафты" ,
},
];
return (
<>
{ data . sort ( sortItems ). map ( el => (
< JournalItem key = { el . id }
title = { el . title }
text = { el . text }
date = { el . date }
/>
))}
</>
);
}
Note
key это важный параметры для элемента списка
Ключи помогают React определять, какие элементы были изменены, добавлены или удалены.
Условный рендер в JSX
condition && < JSX /> рендерит < JSX /> если условие condition вернет true
condition ? < JsxTrue /> : < JsxFalse /> рендерит < JsxTrue /> или < JsxFalse > в зависимости от того , что вернет условие condition .
{ items . length === 0 && < p > Записей пока нет </ p >}
{ items . length > 0 && items . map ( el => ())}
Правильная работа с CSS модулями
import styles from './JournalItem.module.css' ;
< img className = { styles . image }>
Библиотека classNames
Основние использование когда нужно добавить классы по условию
import classNames from 'classnames' ;
className = { classNames ( styles [ 'image' ], {[ styles [ 'image--small' ]] : ifSmall })}
useEffect
Используя этот хук, вы говорите React сделать что-то после рендера.
React запомнит функцию (то есть «эффект»), которую вы передали и вызовет её после того, как внесёт все изменения в DOM.
useEffect говорит что мы должны вызвать какой это эффект при изменении наших зависимостей.
Если зависимости пустые значит он больше никогда не будет триггериться.
const [ items , setItems ] = useState ([]);
const data = JSON . parse ( localStorage . getItem ( 'data' ));
if ( data ) {
setItems ( data );
}
Warning
Такая конструкция вызовет бесконечный ререндинг
Для того чтобы это не происходило, нужно использовать useEffect
useEffect (() => {
console . log ( 'useEffect' );
}, [ items ]);