原文如下:
Making an Interactive Component
Let’s fill the Square component with an “X” when we click it. First, change the button tag that is returned from the Square component’s render()
function to this:
class Square extends React.Component {
render() {
return (
<button className="square" onClick={function() { alert('click'); }}>
{this.props.value}
</button>
);
}
}
If we click on a Square now, we should get an alert in our browser.
Note
To save typing and avoid the confusing behavior of
this
, we will use the arrow function syntax for event handlers here and further below:class Square extends React.Component { render() { return ( <button className="square" onClick={() => alert('click')}> {this.props.value} </button> ); } }
Notice how with
onClick={() => alert('click')}
, we’re passing a function as theonClick
prop. It only fires after a click. Forgetting() =>
and writingonClick={alert('click')}
is a common mistake, and would fire the alert every time the component re-renders.
As a next step, we want the Square component to “remember” that it got clicked, and fill it with an “X” mark. To “remember” things, components use state.
React components can have state by setting this.state
in their constructors. this.state
should be considered as private to a React component that it’s defined in. Let’s store the current value of the Square in this.state
, and change it when the Square is clicked.
First, we’ll add a constructor to the class to initialize the state:
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button className="square" onClick={() => alert('click')}>
{this.props.value}
</button>
);
}
}
Note
In JavaScript classes, you need to always call
super
when defining the constructor of a subclass. All React component classes that have aconstructor
should start it with asuper(props)
call.扫描二维码关注公众号,回复: 5089998 查看本文章
Now we’ll change the Square’s render
method to display the current state’s value when clicked:
- Replace
this.props.value
withthis.state.value
inside the<button>
tag. - Replace the
() => alert()
event handler with() => this.setState({value: 'X'})
. - Put the
className
andonClick
props on separate lines for better readability.
After these changes, the <button>
tag that is returned by the Square’s render
method looks like this:
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button
className="square"
onClick={() => this.setState({value: 'X'})}
>
{this.state.value}
</button>
);
}
}
By calling this.setState
from an onClick
handler in the Square’s render
method, we tell React to re-render that Square whenever its <button>
is clicked. After the update, the Square’s this.state.value
will be 'X'
, so we’ll see the X
on the game board. If you click on any Square, an X
should show up.
When you call setState
in a component, React automatically updates the child components inside of it too.
View the full code at this point