Comment on page
Use 'state' and 'actions'
Now let's learn how we can use
state
and actions
within our theme to develop a bit of interactivity.We're going to add the option to show/hide the URL that sits just under our main heading. We originally used this to display the value of
state.router.link
when we first connected our <Root>
component to the state in an earlier lesson.Open
index.js
at the root of our theme and add a new boolean property called isUrlVisible
in state.theme
. We'll set its default value to false
.// File: /packages/my-first-theme/src/index.js
import Root from "./components"
const myFirstTheme = {
name: "my-first-theme",
roots: {
theme: Root,
},
state: {
theme: {
isUrlVisible: false,
},
},
actions: {
theme: {},
},
}
export default myFirstTheme
Now in the
<HeaderContent>
component within the <Root>
component we'll add some conditional logic to check the value of isUrlVisible
and either display the URL or not. Again we have to use the ternary conditional operator here.// File: /packages/my-first-theme/src/components/index.js
// ...
<Header isPostType={data.isPostType} isPage={data.isPage}>
<HeaderContent>
<h1>Hello Frontity</h1>
{ state.theme.isUrlVisible ? <p>Current URL: {state.router.link}</p> : null }
<Menu>
// ...
</Menu>
</HeaderContent>
</Header>
<Main>
// ...
</Main>
When you save the file you will find that the URL has disappeared, but if you change the value of
isUrlVisible
in index.js
to true
it will reappear. Try it now! (note: you may have to manually refresh the browser)// File: /packages/my-first-theme/src/index.js
//...
state: {
theme: {
isUrlVisible: true,
},
},
//...
As we've just seen, the state of the
isUrlVisible
variable determines whether the URL is visible or not.Next we'll add an action - this is a function, which we'll call
toggleUrl
, that will toggle the value of isUrlVisible
between true and false.NOTE: This is the proper way to mutate state. You should never mutate the state directly from your components. You should, instead, create actions to mutate state and call those actions from your components.
// File: /packages/my-first-theme/src/index.js
import Root from "./components"
const myFirstTheme = {
name: "my-first-theme",
roots: {
theme: Root,
},
state: {
theme: {
isUrlVisible: false,
},
},
actions: {
theme: {
toggleUrl: ({ state }) => {
state.theme.isUrlVisible = !state.theme.isUrlVisible
},
},
},
}
export default myFirstTheme
Let's add some buttons that use the
toggleUrl
action we just added to change the value of isUrlVisible
from the front end.// File: /packages/my-first-theme/src/components/index.js
// ...
const Root = ({ state, actions }) => {
// ...
{ state.theme.isUrlVisible
? <>Current URL: {state.router.link} <button onClick={actions.theme.toggleUrl}>< Hide URL</button></>
: <button onClick={actions.theme.toggleUrl}>Show URL ></button>
}
Note that we have to wrap the
button
element and "Current URL" string in enclosing empty tags <> ... </>
.☝️ Remember too that we need to pass
actions
to the <Root>
component in order to use the toggleUrl
function that we defined earlier.Great, now we can show or hide the URL with user actions in the browser.
Finally let's create a styled
<Button>
component and use it in place of the <button>
element in order to improve the appearance.// File: /packages/my-first-theme/src/components/index.js
// ...
{
state.theme.isUrlVisible ? (
<>
Current URL: {state.router.link}{" "}
<Button onClick={actions.theme.toggleUrl}>< Hide URL</Button>
</>
) : (
<Button onClick={actions.theme.toggleUrl}>Show URL ></Button>
)
}
// ...
const Button = styled.button`
background: transparent;
border: none;
color: #aaa;
:hover {
cursor: pointer;
color: #888;
}
`
Last modified 2yr ago