--- id: 5a24c314108439a4d4036173 title: Set State with this.setState challengeType: 6 forumTopicId: 301412 dashedName: set-state-with-this-setstate --- # --description-- The previous challenges covered component `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: ```jsx this.setState({ username: 'Lewis' }); ``` React expects you to never modify `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](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous) for further details. # --instructions-- There is a `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. # --hints-- The state of `MyComponent` should initialize with the key value pair `{ name: Initial State }`. ```js assert( Enzyme.mount(React.createElement(MyComponent)).state('name') === 'Initial State' ); ``` `MyComponent` should render an `h1` heading element. ```js assert(Enzyme.mount(React.createElement(MyComponent)).find('h1').length === 1); ``` The rendered `h1` heading element should contain text rendered from the component's state. ```js 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(/

TestName<\/h1>/.test(firstValue)); }; ``` Calling the `handleClick` method on `MyComponent` should set the name property in state to equal `React Rocks!`. ```js 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!'); }; ``` # --seed-- ## --after-user-code-- ```jsx ReactDOM.render(, document.getElementById('root')) ``` ## --seed-contents-- ```jsx 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 (

{this.state.name}

); } }; ``` # --solutions-- ```jsx 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 (

{this.state.name}

); } }; ```