Created
June 9, 2025 07:24
-
-
Save sunmeat/db49747833de341eb3a0e022f65eaf0a to your computer and use it in GitHub Desktop.
привязка обработчика события в классовом компоненте
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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