{"id":530,"date":"2018-06-18T14:29:39","date_gmt":"2018-06-18T02:29:39","guid":{"rendered":"https:\/\/content.ronella.xyz\/apps\/wordpress\/?p=530"},"modified":"2018-06-18T14:32:38","modified_gmt":"2018-06-18T02:32:38","slug":"changing-react-component-state","status":"publish","type":"post","link":"https:\/\/www.ronella.xyz\/?p=530","title":{"rendered":"Changing React Component State"},"content":{"rendered":"<h4>Introduction<\/h4>\n<p>React renders component based on any changes on its state <em>(i.e. data)<\/em>.<\/p>\n<h4>Updating State with Form Components<\/h4>\n<p>In React, a form input component controlled by it is known as <strong>controlled component<\/strong>. These components maintains their own state and update itself based on user input as depicted by the following code:<\/p>\n<h6>Code 1 - Controlled Text Input<\/h6>\n<pre>const MessageView = (props) =&gt; {\r\n  return(\r\n    &lt;h1&gt;{props.message}&lt;\/h1&gt;\r\n  );\r\n}\r\n\r\nclass App extends React.Component {\r\n<strong>  state = {\r\n    message : \"\"\r\n  };<\/strong>\r\n\r\n<strong>  handleMsgChange = (event) =&gt; {\r\n    this.setState({\r\n      message: event.target.value\r\n    });\r\n  }<\/strong>\r\n  \r\n  render() {\r\n    return(\r\n        &lt;div&gt;\r\n          &lt;input type=\"text\" placeholder=\"Type Something\" <strong>value={this.state.message}<\/strong> <strong>onChange={this.handleMsgChange}<\/strong>\/&gt;\r\n          &lt;MessageView message={<strong>this.state.message<\/strong>}\/&gt;\r\n      &lt;\/div&gt;\r\n    );\r\n  }\r\n}\r\n\r\nReactDOM.render(&lt;App \/&gt;, mountNode);<\/pre>\n<p>The App component above has a <strong>message attribute<\/strong> in <strong>state <\/strong>as seen in the following snippet:<\/p>\n<h6>Snippet 1 - App Component State<\/h6>\n<pre>state = {\r\n  message : \"\"\r\n};\r\n<\/pre>\n<p>We can bound the message attribute to the text input via the <strong>value attribute<\/strong> and listen to the changes on itself using the <strong>onChange attribute<\/strong> which in turn updates the state of the message like the following snippet:<\/p>\n<h6>Snippet 2 - Controlled Text Input<\/h6>\n<pre>&lt;input type=\"text\" placeholder=\"Type Something\" <strong>value={this.state.message}<\/strong> <strong>onChange={this.handleMsgChange}<\/strong>\/&gt;<\/pre>\n<p>The <strong>handleMsgChange<\/strong>\u00a0that is bound to text input <strong>onChange attribute<\/strong> must update the <strong>message state<\/strong> of the React App component and could have the following implementation. This makes the React state as the single source of truth.<\/p>\n<h6>Snippet 3 - handleMsgChange Implementation<\/h6>\n<pre>handleMsgChange = (event) =&gt; {\r\n  <strong>this.setState({\r\n    message: event.target.value\r\n  });<\/strong>\r\n}<\/pre>\n<p>This particular implementation will also trigger the re-render of the MessageView component since it is also dependent to the state of the message as we can see in the following snippet:<\/p>\n<h6>Snippet 4 - MessageView listening to the State of the Message<\/h6>\n<pre>&lt;MessageView message=<strong>{this.state.message}<\/strong>\/&gt;\r\n<\/pre>\n<h4>Updating State that may be Asynchronous<\/h4>\n<p>React might batch multiple <strong>setState function calls<\/strong> into a single update for performance. Thus the correct way to change the React state is by using the setState function that accepts a function instead of object like the following snippet:<\/p>\n<h6>Snippet 5 - Updating the React State<\/h6>\n<pre>this.setState((prevState, props) =&gt; {\r\n   \/\/Do the state update here.\r\n})<\/pre>\n<p>Let us try to create a reusable\u00a0<strong>ButtonClear component<\/strong> that will clear value of the message attribute with the following snippet.<\/p>\n<h6>Snippet 6 - ButtonClear Component<\/h6>\n<pre style=\"white-space: pre;\">const ButtonClear = (props) =&gt; {\r\n  if (<strong>props.visible<\/strong>) {\r\n    return(\r\n        &lt;button onClick=<strong>{props.handleClear}<\/strong>&gt;Clear&lt;\/button&gt;\r\n    );\r\n  }\r\n  return(null); \/\/Returns nothing\r\n}\r\n<\/pre>\n<p>Based on the preceding snippet the ButtonClean component will only display the <strong>clear button<\/strong> if we tell it to make it visible via its <strong>visible attribute<\/strong>. Moreover, it is also expecting to have a <strong>handleClear implementation<\/strong> that will be bound to button's\u00a0<strong>onClick attribute<\/strong>.<\/p>\n<p>The <strong>handleClear implementation<\/strong> will be provided by the App component like the following snippet with the recommended usage of the setState() function:<\/p>\n<h6>Snippet 7 - App Component handleClear Implementation<\/h6>\n<pre>handleClear = () =&gt; {\r\n<strong>  this.setState((prevState, props) =&gt; {\r\n    return {message: \"\"}; \/\/Clears the message\r\n  });<\/strong>\r\n}<\/pre>\n<p>Thus we can use the ButtonClear component in the App component like the following snippet:<\/p>\n<h6>Snippet 8 - Using the ButtonClear in the App Component<\/h6>\n<pre style=\"white-space: pre;\">&lt;ButtonClear <strong>handleClear={this.handleClear}<\/strong> <strong>visible={this.state.message!=\"\"}<\/strong>\/&gt;<\/pre>\n<p>We also instructed it to make the clear button visible only if the message is not empty.<\/p>\n<p>The updated complete code with ButtonClear component can be seen as follows:<\/p>\n<h6>Code 2 - The Complete Code<\/h6>\n<pre style=\"white-space: pre;\">const MessageView = (props) =&gt; {\r\n  return(\r\n    &lt;h1&gt;{props.message}&lt;\/h1&gt;\r\n  );\r\n}\r\n\r\n<strong>const ButtonClear = (props) =&gt; {\r\n  if (props.visible) {\r\n    return(\r\n        &lt;button onClick={props.handleClear}&gt;Clear&lt;\/button&gt;\r\n    );\r\n  }\r\n  return(null);\r\n}<\/strong>\r\n\r\nclass App extends React.Component {\r\n  state = {\r\n    message : \"\"\r\n  };\r\n\r\n  handleMsgChange = (event) =&gt; {\r\n    this.setState({\r\n      message: event.target.value\r\n    });\r\n  }\r\n  \r\n<strong>  handleClear = () =&gt; {\r\n    this.setState((prevState, props) =&gt; {\r\n      return {message: \"\"}; \/\/Clears the message.\r\n    });\r\n  }<\/strong>\r\n  \r\n  render() {\r\n    return(\r\n        &lt;div&gt;\r\n          &lt;input type=\"text\" placeholder=\"Type Something\" value={this.state.message} onChange={this.handleMsgChange}\/&gt;\r\n          <strong>&lt;ButtonClear handleClear={this.handleClear} visible={this.state.message!=\"\"}\/&gt;<\/strong>\r\n          &lt;MessageView message={this.state.message}\/&gt;\r\n      &lt;\/div&gt;\r\n    );\r\n  }\r\n}\r\n\r\nReactDOM.render(&lt;App \/&gt;, mountNode);<\/pre>\n<p><em>Note: We can run both <strong>Code 1<\/strong> and <strong>Code 2<\/strong> using\u00a0<a href=\"https:\/\/jscomplete.com\/repl\" target=\"_blank\" rel=\"noopener\">jsComplete Playground<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction React renders component based on any changes on its state (i.e. data). Updating State with Form Components In React, a form input component controlled by it is known as controlled component. These components maintains their own state and update itself based on user input as depicted by the following code: Code 1 &#8211; Controlled [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[38,39],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/530"}],"collection":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=530"}],"version-history":[{"count":31,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/530\/revisions"}],"predecessor-version":[{"id":561,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/530\/revisions\/561"}],"wp:attachment":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}