{"id":7537,"date":"2019-11-01T22:42:39","date_gmt":"2019-11-01T22:42:39","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=7537"},"modified":"2019-11-01T22:45:08","modified_gmt":"2019-11-01T22:45:08","slug":"react-context","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/react-context\/","title":{"rendered":"React context (developing a ThemeProvider)"},"content":{"rendered":"<p>I&#8217;ve been looking into theming a React project and whilst I ultimately intended to use the theming capabilities within material-ui I was interested in how I might write our own.<\/p>\n<p>We&#8217;re going to be using <a href=\"https:\/\/reactjs.org\/docs\/context.html\" rel=\"noopener noreferrer\" target=\"_blank\">React context<\/a>.<\/p>\n<p>Let&#8217;s start by creating a theme.ts file which will include our &#8220;base&#8221; theme style<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nexport const theme = {\r\n  button: {\r\n    backgroundColor: &quot;white&quot;,\r\n    borderColor: &quot;red&quot;,\r\n    color: &quot;blue&quot;,\r\n    borderWidth: &quot;2px&quot;,\r\n    borderStyle: &quot;solid&quot;,\r\n    padding: &quot;10px&quot;,\r\n    fontSize: &quot;24px&quot;,\r\n  }\r\n};\r\n<\/pre>\n<p>In the above code we created a button property which obviously defines our (rather horrible) default button style. Now we need some way to apply this theme (and any new version of our theme) to our application. <\/p>\n<p>Hence we create a ThemeProvider (ThemeProvider.tsx in my case), which looks like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport React from &quot;react&quot;;\r\nimport { theme } from &quot;..\/theme&quot;;\r\n\r\nexport const ThemeContext = React.createContext(theme);\r\n\r\nexport function ThemeProvider(props: any) {\r\n  return (\r\n    &lt;ThemeContext.Provider value={props.theme}&gt;\r\n      {props.children}\r\n    &lt;\/ThemeContext.Provider&gt;\r\n  );\r\n}\r\n<\/pre>\n<p>In this case, we create a React context, and assign a default value to it (in the shape of our base theme). The ThemeProvider function is then used to wrap our application supplying the theme to all components that wish to use it. So here&#8217;s an example of the ThemeProvider in use (in the App.tsx)<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport React from 'react';\r\nimport { ThemeProvider } from '.\/components\/ThemeProvider';\r\nimport { Button } from '.\/components\/Button';\r\nimport { myTheme } from '.\/myTheme';\r\n\r\nconst App: React.FC = () =&gt; {\r\n  return (\r\n    &lt;ThemeProvider theme={myTheme}&gt;\r\n      &lt;div className=&quot;App&quot;&gt;\r\n        &lt;Button&gt;Themed Button&lt;\/Button&gt;\r\n      &lt;\/div&gt;\r\n    &lt;\/ThemeProvider&gt;\r\n  );\r\n}\r\n\r\nexport default App;\r\n<\/pre>\n<p>You&#8217;ll notice we&#8217;ve also taken this opportunity to supply our overridden theme (with a slightly nicer button style) which is shown below (myTheme.ts)<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nexport const myTheme = {\r\n  button: {\r\n    backgroundColor: &quot;green&quot;,\r\n    color: &quot;white&quot;,\r\n    borderWidth: &quot;2px&quot;,\r\n    borderStyle: &quot;solid&quot;,\r\n    padding: &quot;10px&quot;,\r\n    fontSize: &quot;24px&quot;,\r\n  }\r\n};\r\n<\/pre>\n<p>As you can see from our App.tsx code, we&#8217;re using a Button component, so let&#8217;s look at that code now (Button.tsx)<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport React from &quot;react&quot;;\r\nimport { ThemeContext } from &quot;.\/ThemeProvider&quot;;\r\n\r\nexport const Button = (props: any) =&gt; (\r\n  &lt;ThemeContext.Consumer&gt;\r\n    {theme =&gt; (\r\n      &lt;button style={theme.button} {...props}&gt;\r\n        {props.children}\r\n      &lt;\/button&gt;\r\n    )}\r\n  &lt;\/ThemeContext.Consumer&gt;\r\n);\r\n<\/pre>\n<p>In this code we consume the React context we created via the ThemeProvider file and apply the style to the button, also passing through any props to the button.<\/p>\n<p>Now if you were to run this application the button will be displayed with our new theme (a nice green background button). If you change the App.tsx theme property to the default &#8220;base&#8221; theme, then we our default style.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been looking into theming a React project and whilst I ultimately intended to use the theming capabilities within material-ui I was interested in how I might write our own. We&#8217;re going to be using React context. Let&#8217;s start by creating a theme.ts file which will include our &#8220;base&#8221; theme style export const theme = [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[243],"tags":[],"class_list":["post-7537","post","type-post","status-publish","format-standard","hentry","category-react"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=7537"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7537\/revisions"}],"predecessor-version":[{"id":7568,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7537\/revisions\/7568"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=7537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=7537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=7537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}