Как обрабатывать события в React приложении
2 года назад·2 мин. на чтение
В этой статье рассмотрим как обработать события в React, а также о том, почему мы связываем ключевое слово `this` в классовых компонентах React.
В JSX нам нужно обернуть выражения JavaScript фигурными скобками
{ }
.
Обычный JavaScript:
В ReactJS:<button onclick="hitMe()">hit me</button>
Рассмотрим подробнее, как присоединить обработчики событий в функциональных и классовых компонентах.<button onClick={hitMe}>hitme</button>
Функциональные компоненты
В React нам нужно передать функцию обработчика событий.function Button() { function handleClick() { alert('some one clicked me') } return ( <button onClick={handleClick}>Click me</button> ) }
Передача аргументов
Мы также можем передавать аргументы в функции обработчика событий, подобные этой.function Button() { function handleClick(name) { alert(name) } return ( <button onClick={()=>handleClick('react')}>Click me</button> ) }
Классовые компоненты
В компонентах на основе классов нам нужно привязатьclass Counter extends React.Component { constructor(props) { super(props); this.state = { num: 0 } } handleInc(){ this.setState({ num: this.state.num+1 }) } render(){ return ( <div> <h1>Counter</h1> <h3>{this.state.num}</h3> <button onClick={this.handleInc.bind(this)}>Increment</button> </div> ) } }
this
к классу, иначе this
будет привязано к global window object
или в строгом режиме this
будет undefined
.
Мы можем решить эту проблему с помощью стрелочных функций, потому что в стрелочных функциях this
будет привязано к его внешнему контексту выполнения.
Давайте модифицируем приведенный выше компонент с помощью стрелочных функций.
class Counter extends React.Component { constructor(props) { super(props); this.state = { num: 0 } } handleInc() { this.setState({ num: this.state.num+1 }) } render(){ return ( <div> <h1>Counter</h1> <h3>{this.state.num}</h3> <button onClick={()=>this.handleInc()}>Increment</button> </div> ) } }
Второй способ использования class fields syntax
class Counter extends React.Component { constructor(props) { super(props); this.state = { num: 0 } } // стрелочная функция handleInc = () => { this.setState({ num: this.state.num+1 }) } render() { return ( <div> <h1>Counter</h1> <h3>{this.state.num}</h3> <button onClick={this.handleInc}>Increment</button> </div> ) } }
Объект события
Мы также можем использовать объект события таким образом в react.function Link(){ function handleClick(e){ console.log(e); e.preventDefault(); } return ( <a href="#" onClick={handleClick} >Click me</a> ) }
Проп key для пересоздания компонента в ReactJS
2 года назад·2 мин. на чтение
Знали ли вы, что проп key может быть полезен не только при рендеринге списка компонентов. Проп key можно использовать и для того чтобы сбросить состояние одного компонента.
Что такое проп key
в ReactJS?
Это специальный проп, который может быть добавлен к любому компоненту. Он помогает механизму reconciliation (согласование), упрощая сравнение компонентов. Типичный сценарий использования key
- добавление его в компоненты списка. Он нужен для того чтобы React понимал, какой компонент списка был добавлен, удален или изменен.
const notes = [ { id: 1, title: 'React hooks', }, { id: 2, title: 'JSX', }, { id: 3, title: 'Redux', }, ]; const NotesList = ({ notes, onClick }) => { return ( <div className="notes-list"> {notes.map((note) => ( <p className="notes-list__item" key={note.id} onClick={() => onClick(note)} > {note.title} </p> ))} </div> ); };
Проп key
работает и вне списков
Проп key
может быть добавлен к абсолютно любому компоненту для того, чтобы сбросить нежелательное состояние этого компонента.
Например, в списке заметок есть поле для ввода текста. Если просто добавить это поле и ввести в него текст, то при выборе новой заметки слева - текст будет сохраняться. И, предположим, при выборе заметки мы хотим очистить это поле.
function App() { const [activeNote, setActiveNote] = useState(); const handleClick = (note) => { setActiveNote(note); }; return ( <div className="notes-container"> <NotesList notes={notes} onClick={handleClick} /> <Note title={activeNote?.title} /> </div> ); }
Это можно сделать, например, добавив пропconst Note = ({ title }) => { const [text, setText] = useState(); const handleChange = (event) => { setText(event.target.value); }; return ( <div className="note"> <p>{title}</p> <textarea className="note-textarea" value={text} onChange={handleChange} /> </div> ); };
text
в компонент Note
. И далее очищать его при изменении состояния activeNote
. Но изменение компонентов может быть невозможным, если мы используем компоненты из third-party библиотеки.
Сброс состояние экземпляра компонента
Пропkey
помогает React идентифицировать компонент. Его также можно использовать, чтобы сообщить React, что идентификатор компонента изменился и это вызовет полное повторное создание этого компонента. Добавим key={activeNote?.id}
к компоненту <Note />
.
Теперь, при изменении// ... return ( <div className="notes-container"> <NotesList notes={notes} onClick={handleClick} /> <Note title={activeNote?.title} key={activeNote?.id} /> </div> ); }
key
React пересоздаст компонент <Note />
.
Влияние на производительность
Хотя это хороший прием, который уменьшает количество кода, важно иметь ввиду, что этот подход заставляет React пересоздавать весь экземпляр компонента. В примере выше большая часть компонента<Note />
будет перерисована в любом случае при изменении activeNote
. Поэтому в этом случае это достаточно хорошее решение.
В реальных приложениях нужно ограничивать добавление key
к одиночным компонентам вне списков, а также избегать добавления key
на компоненты верхнего уровня. Это может стать причиной проблем с производительностью, которые трудно обнаружить.