5.6 KiB
5.6 KiB
id | title | challengeType | isRequired |
---|---|---|---|
5a24c314108439a4d4036173 | Set State with this.setState | 6 | false |
Description
state
and how to initialize state in the constructor
. There is also a way to change the component's state
. React provides a method for updating component state
called setState
. You call the setState
method within your component class like so: this.setState()
, passing in an object with key-value pairs. The keys are your state properties and the values are the updated state data. For instance, if we were storing a username
in state and wanted to update it, it would look like this:
this.setState({React expects you to never modify
username: 'Lewis'
});
state
directly, instead always use this.setState()
when state changes occur. Also, you should note that React may batch multiple state updates in order to improve performance. What this means is that state updates through the setState
method can be asynchronous. There is an alternative syntax for the setState
method which provides a way around this problem. This is rarely needed but it's good to keep it in mind! Please consult the React documentation for further details.
Instructions
button
element in the code editor which has an onClick()
handler. This handler is triggered when the button
receives a click event in the browser, and runs the handleClick
method defined on MyComponent
. Within the handleClick
method, update the component state
using this.setState()
. Set the name
property in state
to equal the string React Rocks!
.
Click the button and watch the rendered state update. Don't worry if you don't fully understand how the click handler code works at this point. It's covered in upcoming challenges.
Tests
tests:
- text: 'The state of <code>MyComponent</code> should initialize with the key value pair <code>{ name: Initial State }</code>.'
testString: 'assert(Enzyme.mount(React.createElement(MyComponent)).state(''name'') === ''Initial State'', ''The state of <code>MyComponent</code> should initialize with the key value pair <code>{ name: Initial State }</code>.'');'
- text: <code>MyComponent</code> should render an <code>h1</code> header.
testString: assert(Enzyme.mount(React.createElement(MyComponent)).find('h1').length === 1, '<code>MyComponent</code> should render an <code>h1</code> header.');
- text: The rendered <code>h1</code> header should contain text rendered from the component's state.
testString: 'async () => { const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250)); const mockedComponent = Enzyme.mount(React.createElement(MyComponent)); const first = () => { mockedComponent.setState({ name: ''TestName'' }); return waitForIt(() => mockedComponent.html()); }; const firstValue = await first(); assert(/<h1>TestName<\/h1>/.test(firstValue), ''The rendered <code>h1</code> header should contain text rendered from the component's state.''); };'
- text: Calling the <code>handleClick</code> method on <code>MyComponent</code> should set the name property in state to equal <code>React Rocks!</code>.
testString: 'async () => { const waitForIt = (fn) => new Promise((resolve, reject) => setTimeout(() => resolve(fn()), 250)); const mockedComponent = Enzyme.mount(React.createElement(MyComponent)); const first = () => { mockedComponent.setState({ name: ''Before'' }); return waitForIt(() => mockedComponent.state(''name'')); }; const second = () => { mockedComponent.instance().handleClick(); return waitForIt(() => mockedComponent.state(''name'')); }; const firstValue = await first(); const secondValue = await second(); assert(firstValue === ''Before'' && secondValue === ''React Rocks!'', ''Calling the <code>handleClick</code> method on <code>MyComponent</code> should set the name property in state to equal <code>React Rocks!</code>.''); };'
Challenge Seed
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Initial State'
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// change code below this line
// change code above this line
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click Me</button>
<h1>{this.state.name}</h1>
</div>
);
}
};
After Test
ReactDOM.render(<MyComponent />, document.getElementById('root'))
Solution
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Initial State'
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// change code below this line
this.setState({
name: 'React Rocks!'
});
// change code above this line
}
render() {
return (
<div>
<button onClick = {this.handleClick}>Click Me</button>
<h1>{this.state.name}</h1>
</div>
);
}
};