Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created June 9, 2025 07:24
Show Gist options
  • Save sunmeat/db49747833de341eb3a0e022f65eaf0a to your computer and use it in GitHub Desktop.
Save sunmeat/db49747833de341eb3a0e022f65eaf0a to your computer and use it in GitHub Desktop.
привязка обработчика события в классовом компоненте
import React, {useState, useEffect} from 'react';
import './App.css';
const getTimeWithMicroseconds = () => {
const now = new Date();
const micros = Math.floor(performance.now() * 1000) % 1000000;
return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${micros.toString().padStart(6, '0')}`;
};
const FunctionalButton = ({width, height, color, text}) => {
const [clickCount, setClickCount] = useState(0);
useEffect(() => {
console.log('функциональная кнопка смонтирована ' + getTimeWithMicroseconds());
return () => {
console.log('функциональная кнопка размонтирована ' + getTimeWithMicroseconds());
};
}, []);
useEffect(() => {
console.log('функциональная кнопка ' + getTimeWithMicroseconds() + ' обновлена с clickCount =', clickCount);
}, [clickCount]);
const handleClick = () => {
setClickCount(clickCount + 1);
};
return (
<div className="button-container">
<button
className="custom-button"
style={{width, height, background: `linear-gradient(135deg, ${color}, ${color}CC)`}}
onClick={handleClick}
>
{text}
</button>
<p className="click-text">Functional Button Clicks: {clickCount}</p>
</div>
);
};
// классовый компонент
class ClassButton extends React.Component {
constructor(props) {
super(props);
this.state = {
clickCount: 0,
};
// привязываем handleClick к экземпляру класса
this.handleClick = this.handleClick.bind(this); // попробуйте закомментировать :)
// привязка метода this.handleClick = this.handleClick.bind(this); в конструкторе
// необходима в классовых компонентах, чтобы обеспечить правильный контекст this
// при вызове метода handleClick в обработчике события, например,
// в <button onClick={this.handleClick}>. без этой привязки this внутри handleClick
// будет undefined, что приведёт к ошибке при попытке доступа к this.setState или
// другим свойствам экземпляра класса.
// в JavaScript контекст this в функции зависит от того, как функция вызывается.
// в React, когда при передаче метода класса как обработчика события, например,
// onClick={this.handleClick}, этот метод вызывается в контексте события,
// а не в контексте экземпляра класса. в результате this внутри handleClick
// не указывает на экземпляр ClassButton, что делает невозможным доступ
// к this.setState или this.props!!
}
componentDidMount() {
console.log('классовая кнопка смонтирована ' + getTimeWithMicroseconds());
}
componentDidUpdate(prevProps, prevState) {
if (prevState.clickCount !== this.state.clickCount) {
console.log('классовая кнопка обновлена ' + getTimeWithMicroseconds() + ' с clickCount =', this.state.clickCount);
}
}
componentWillUnmount() {
console.info('классовая кнопка размонтирована ' + getTimeWithMicroseconds());
}
// обработчик кликов
handleClick() {
this.setState({clickCount: this.state.clickCount + 1});
}
render() {
const {width, height, color, text} = this.props;
return (
<div className="button-container">
<button
className="custom-button"
style={{width, height, background: `linear-gradient(135deg, ${color}, ${color}CC)`}}
onClick={this.handleClick}
>
{text}
</button>
<p className="click-text">Class Button Clicks: {this.state.clickCount}</p>
</div>
);
}
}
const App = () => {
return (
<div className="app-container">
<FunctionalButton
width="200px"
height="50px"
color="#4CAF50"
text="Functional Button"
/>
<ClassButton
width="200px"
height="50px"
color="#2196F3"
text="Class Button"
/>
</div>
);
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment