Потому-что когда вы вызываете метод на объекте:
obj.method(); // вызываем метод
или:
this.method(); // вызываем метод
Ссылка на объект указанная перед точкой будет использована в качестве контекста и будет доступна в функции, через ключевое слово this.
Когда вы передаете метод без вызова:
onClick={obj.method} // не вызываем метод
или:
onClick={this.method} // не вызываем метод
Передается лишь метод, а контекст теряется.
Чтобы не терялся контекст при передаче метода в слушатель, можно использовать функцию
bind. На вашем примере:
class MainPage extends Component {
constructor(props) {
super(props);
this.state = {
color: 'red'
};
this.changeStylesForCaption = this.changeStylesForCaption.bind(this); // привязываем контекст
}
changeStylesForCaption() {
this.setState({
color: 'black'
});
}
render() {
return (
<h1 onClick={this.changeStylesForCaption} style={{ color: this.state.color }}>gleb</h1>
);
}
}
Стрелочные функции контекста не имеют и используют контекст того окружения, где они определены.