ChatGPT на русском языке, бесплатноНовости и обновления в Telegram
На sponsr есть решения ваших задач
Полезные видео о фронтенде. Подпишись на Rutube
11 ошибок, которых следует избегать при создании React приложений
2 года назад·7 мин. на чтение
Некоторые распространенные ошибки в разработке React приложений, которых следует избегать.
Поскольку React становится все более и более популярным, все больше и больше React разработчиков сталкиваются с различными проблемами в процессе разработки.
В этой статье, мы обобщим некоторые распространенные ошибки в разработке React приложений, чтобы помочь вам их избежать.
Если вы только начинаете использовать React, рекомендуется внимательно ознакомиться с этой статьей. Если вы уже используете React для разработки проектов, также рекомендуется проверить и заполнить пробелы.
Прочитав эту статью, вы узнаете, как избежать эти 11 ошибок React:
Ошибка: При рендеринге списка не используется
Проблема
Когда мы впервые изучали React, мы отображали список следующим образом:
Ошибка: Использование состояния сразу после выполнения
Проблема
Когда мы изменяем данные через
Ошибка: Появление бесконечного цикла при использовании
Проблема
Когда мы напрямую вызываем метод
Приведем 4 случая использования
Ошибка: Отсутствие очистки побочных эффектов в
Проблема
В классовых компонентах мы используем метод жизненного цикла
- При рендеринге списка не используется
key
- Изменение значения состояния прямым присваиванием
- Привязка значения состояния непосредственно к свойству value инпута
- Использование состояния сразу после выполнения
setState
- Появление бесконечного цикла при использовании
useState
+useEffect
- Отсутствие очистки побочных эффектов в
useEffect
- Неправильное использование логических операторов
- Тип пропсов компонента не типизирован
- Передача строк в качестве значений компонентам
- Имя компонента не начинается с заглавной буквы
- Неверная привязка события к элементу
Ошибка: При рендеринге списка не используется key
Проблема
Когда мы впервые изучали React, мы отображали список следующим образом:
После рендеринга консоль выдаст предупреждение, что для элементов списка необходимо указать ключ. Решение Вам просто нужно последовать этой подсказке и добавитьconst items = [ { id: 1, value: 'item1' }, { id: 2, value: 'item2' }, { id: 3, value: 'item3' }, { id: 4, value: 'item4' }, { id: 5, value: 'item5' } ]; const listItems = items.map((item) => { return <li>{item.value}</li> });
key
к каждому элементу:
const items = [ { id: 1, value: ‘item1’ }, { id: 2, value: ‘item2’ }, { id: 3, value: ‘item3’ }, { id: 4, value: ‘item4’ }, { id: 5, value: ‘item5’ } ]; const listItems = items.map((item) => { return <li key={item.id}>{item.value}</li> });
key
помогает React определить, какие элементы были изменены, например, добавлены или удалены. Поэтому нам нужно установить уникальное значение ключа для каждого элемента в массиве.
Для значения ключа лучше всего установить уникальное значение. В приведенном выше примере используется id
. Можно использовать индекс массива, но такой подход не рекомендуется.
Уникальный ключ помогает React следить за изменениями списка - какой элемент удалился или переместился.
Ошибка: Изменение значения состояния прямым присваиванием
Проблема В React нельзя назначать состояние и изменять напрямую, иначе это вызовет проблемы.В этот момент будет выдано предупреждение не изменять состояние напрямую, а использовать// классовый компонент handleChange = () => { this.state.name = "John"; };
setState()
.
Решение
Классовые компоненты могут быть изменены с помощью setState()
, а функциональные компоненты могут быть изменены с помощью useState()
:
// Классовые компоненты: используйте setState() this.setState({ name: "John" }); // Функциональные компоненты:используйте useState() const [name, setName] = useState(""); setName("John");
Ошибка: Привязка значения состояния непосредственно к свойству value инпута
Проблема Когда мы напрямую привязываем значение состояния к свойствуvalue
инпута, мы обнаружим, что независимо от того, что мы вводим в поле ввода, содержимое поля ввода не изменится.
Это связано с тем, что мы используем переменную состояния в качестве значения по умолчанию для присвоения значенияexport default function App() { const [count, setCount] = useState(0); return <input type="text" value={count} />; }
<input>
, а состояние в функциональном компоненте может быть изменено только функцией set*
, возвращаемым useState
. Таким образом, решение также очень простое, просто используйте функцию set*
при изменении. Подробнее о том как работать с инпутом в React можно прочитать в этой статье.
Решение
Просто привяжите событие onChange
к <input>
и измените его, вызвав setCount
:
export default function App() { const [count, setCount] = useState(0); const handleChange= (event) => setCount(event.target.value); return <input type="text" value={count} onChange={handleChange} />; }
Ошибка: Использование состояния сразу после выполнения setState
Проблема
Когда мы изменяем данные через setState()
и сразу же хотим получить новые данные, возникнет ситуация, что возвращаются старые данные:
Это связано с тем, что// Классовые компоненты // инициализация состояния this.state = { name: "John" }; // обновление состояния this.setState({ name: "Hello, John!" }); console.log(this.state.name); // => John
setState()
является асинхронным. Когда setState()
выполняется, реальная операция обновления будет помещена в асинхронную очередь для выполнения, а код, который будет выполняться следующим (т.е. console.log
в примере), выполняется синхронно, поэтому выводимое в консоль состояние не является последним значением.
Решение
Просто передайте последующую операцию, которая будет выполняться как функция, в качестве второго параметра setState()
, эта функция обратного вызова будет выполнена после завершения обновления.
Теперь обновленное значение выводится правильно.this.setState({ name: "Hello, John!" }, () => { console.log(this.state.name); // => Hello, John! });
Ошибка: Появление бесконечного цикла при использовании useState
+ useEffect
Проблема
Когда мы напрямую вызываем метод set*()
, возвращаемый useState()
внутри useEffect()
, и не устанавливаем второй параметр в useEffect()
, мы столкнемся с бесконечным циклом:
После этого можно увидеть, что данные на странице обновляются, и функцияexport default function App() { const [count, setCount] = useState(0); useEffect(() => { setCount(count + 1); }); return <div className="App">{count}</div>; }
useEffect()
вызывается бесконечно, входя в состояние бесконечного цикла.
Решение
Это распространенная проблема неправильного использования useEffect()
. useEffect()
можно рассматривать как комбинацию трех функций жизненного цикла: componentDidMount
, componentDidUpdate
и componentWillUnmount
в классовых компонентах. useEffect(effect, deps)
принимает 2 аргумента:
effect
функция, которая должна выполниться (побочный эффект)deps
массив зависимостей
deps
выполняется функция эффекта. Чтобы изменить метод, вам нужно всего лишь передать []
в качестве второго аргумента useEffect()
:
export default function App() { const [count, setCount] = useState(0); useEffect(() => { setCount(count + 1); }, []); return <div className="App">{count}</div>; }
useEffect
:
- Если второй параметр не передан: при обновлении любого состояния будет запущена функция эффекта
useEffect
.
useEffect(() => { setCount(count + 1); });
- Если второй параметр - это пустой массив: функция эффекта
useEffect
срабатывает только при монтировании и размонтировании.
useEffect(() => { setCount(count + 1); }, []);
- Если второй параметр представляет собой массив с одним значением: функция эффекта
useEffect
будет запускаться только при изменении значения.
useEffect(() => { setCount(count + 1); }, [name]);
- Если второй параметр представляет собой массив c несколькими значениями: функция эффекта
useEffect
будет запускаться при изменении хотя бы одного из значений из списка зависимостей.
useEffect(() => { setCount(count + 1); }, [name, age]);
Ошибка: Отсутствие очистки побочных эффектов в useEffect
Проблема
В классовых компонентах мы используем метод жизненного цикла componentWillUnmount()
для очистки некоторых побочных эффектов, таких как таймеры, слушатели событий и т. д.
Решение
Из функции эффекта useEffect()
может быть возвращена функция очистки, которая аналогична роли метода жизненного цикла componentWillUnmount()
:
useEffect(() => { // ... return () => clearInterval(id); }, [name, age]);
Ошибка: Неправильное использование логических операторов
Проблема В синтаксисе JSX/TSX мы часто используем логические значения для управления отображаемыми элементами, и во многих случаях мы используем оператор&&
для обработки этой логики:
Мы думаем, что в это время страница будет отображать пустой контент, но на самом деле на ней отобразитсяconst count = 0; const Comp = () => count && <h1>Chris1993</h1>;
0
.
Решение
Причина в том, что ложное выражение приводит к тому, что элементы после &&
пропускаются, и будет возвращено значение ложного выражения. Поэтому нужно стараться написать условие оценки как можно более полным, не полагаясь на истинное и ложное логическое значение JavaScript для сравнения:
Теперь страница будет отображать пустой контент, как и ожидается.const count = 0; const Comp = () => count > 0 && <h1>Chris1993</h1>;
Ошибка: Типы просов компонента не типизированы
Проблема Если компоненты, разработанные разными членами команды, не имеют четко определенных типов для просов, то для коллег будет не очевидно, как использовать компоненты, например:Решениеconst UserInfo = (props) => { return ( <div> {props.name} : {props.age} </div> ); };
- Определить типы пропсов компонента, используя TypeScript.
// Классовые компоненты interface AppProps { value: string; } interface AppState { count: number; } class App extends React.Component<AppProps, AppStore> { // ... } // Функциональные компоненты interface AppProps { value?: string; } const App: React.FC<AppProps> = ({ value = "", children }) => { //... };
- Без использования TypeScript типы пропсов могут быть определены с помощью
propTypes
.
const UserInfo = (props) => { return ( <div> {props.name} : {props.age} </div> ); }; UserInfo.propTypes = { name: PropTypes.string.isRequired, age: PropTypes.number.isRequired, };
Ошибка: Передача строк в качестве значений компонентам
Проблема Так как React имеет шаблонный синтаксис, очень похожий на HTML, часто бывает так, что числа передаются напрямую компонентам в пропсы, что приводит к неожиданному результату:Сравнение<MyComp count="99"></MyComp>
props.count === 99
в компоненте MyComp
вернет false
.
Решение
Правильный способ должен заключаться в использовании фигурных скобок для передачи пропсов:
Передача строковых просов будет выглядеть следующим образом:<MyComp count={99}></MyComp>
<MyComp count={"99"}></MyComp>
Ошибка: Имя компонента не начинается с заглавной буквы
Проблема Начинающие разработчики часто забывают называть свои компоненты с заглавной буквы. Компоненты, начинающиеся со строчной буквы в JSX/TSX, компилируются в элементы HTML, такие как<div />
для тегов HTML.
Решение Просто измените первую букву на заглавную:class myComponent extends React.component {}
class MyComponent extends React.component {}
Ошибка: Неверная привязка события к элементу в классовых компонентах
ПроблемаПри нажатии на кнопкуimport { Component } from "react"; export default class HelloComponent extends Component { constructor() { super(); this.state = { name: "John", }; } update() { this.setState({ name: "Hello John!" }); } render() { return ( <div> <button onClick={this.update}>update</button> </div> ); } }
update
консоль сообщит об ошибке, что невозможно прочитать свойства undefined
(чтение setState
)
Решение
Это происходит потому, что this
не привязан к тому контексту, который мы ожидаем. Есть несколько решений:
- Привязать контекст в конструкторе при помощи метода
bind
constructor() { super(); this.state = { name: "John" }; this.update = this.update.bind(this); }
- Использовать стрелочные функции
update = () => { this.setState({ name: "Hello John!" }); };
- Привязать прямо в функции рендеринга
<button onClick={this.update.bind(this)}>update</button>
- Использовать стрелочные функции в функции рендеринга (не рекомендуется, т.к. это создает новую функцию каждый раз при рендеринге компонента, что влияет на производительность)
<button onClick={() => this.update()}>update</button>
Что делает фронтенд разработчик?
год назад·3 мин. на чтение
Когда вы начинаете изучать особенности карьеры в области веб-разработки, вам может быть интересно, чем занимается фронтенд разработчик.
Проще говоря, фронтенд разработчики сосредоточены на аспектах сайта, обращенных к посетителям, в отличие от backend разработчиков, которые сосредоточены на закулисной работе, или fullstack разработчиков, которые работают со всеми аспектами приложения.
Многие задачи, которые разработчик решает ежедневно, требуют таких навыков, как знание JavaScript или HTML. В этой статье рассмотрим различные инструменты и технологии, которые используют эти специалисты в своей повседневной работе, а также о навыках, необходимых для успешной работы в этой области.
Что делает фронтенд разработчик
Ответственность фронтенд разработчика можно описать таким общим утверждением: обеспечить, чтобы посетители веб приложения могли легко взаимодействовать со страницами приложения (или веб-сайта). Для этого они используют сочетание дизайна, технологий и программирования для создания внешнего вида сайта, а также занимаются отладкой. Когда вы заходите на сайт, все, что вы видите, на что нажимаете или чем пользуетесь - это работа фронтенд разработчика.Общие задачи фронтенд разработчика
Хотя в разных компаниях существуют определенные различия, в целом можно ожидать, что роль фронтенд разработчика будет включать в себя некоторые или все из перечисленных ниже задач:- Оптимизация пользовательского опыта
- Использование HTML, JavaScript и CSS для воплощения концепций в жизнь
- Разработка и поддержка пользовательского интерфейса
- Реализация дизайна на мобильных сайтах
- Создание инструментов, улучшающих взаимодействие с сайтом независимо от браузера
- Управление рабочим процессом программного обеспечения
- Следование лучшим практикам SEO
- Исправление ошибок и тестирование на удобство использования