Making a togglable component
Components can be easily made to toggle from hidden to shown if we have a wrapper component that controls the visibility. In my use case, I want to manage the visibility of a login form, but it can really be anything.
In order to build a Togglable component, I used the useState hook to add a visible state variable.
useStatetakes an initial state and returns two values, the current state and a function that updates the state. For example, in our Togglable component:
const [visible, setVisible] = useState(false);
visiblekeeps track of whether or not our login form is visible. When our page with this component is first rendered, our login form should not be visible sovisibleis first set tofalse.setVisibleis used whenever we want to update the visibility of the form. In our example, we want to show the form when theSign inbutton is clicked. We can write a function to toggle the visibility:
const toggleVisibility = () => {
setVisible(!visible);
};
We can then define two variables hideWhenVisible and showWhenVisible to store the appropriate CSS style for display depending on the state of visible:
const hideWhenVisible = { display: visible ? 'none' : '' }
const showWhenVisible = { display: visible ? '' : 'none' }
Our Togglable component will take in a props object that has props.buttonLabel and props.children. The text for the button that does the toggling is passed down through the Togglable component's buttonLabel attribute. props.children is the component wrapped by the Togglable component. For example:
<Togglable buttonLabel='Sign in'>
<LoginForm />
</Togglable>
It's interesting to note here that React components can take on two forms: <Togglable>{children}</Togglable> or <LoginForm/>. The first is useful when wrapping another component and we can access that child component through props.children or when we don't need child components, we just use the second form.
The code for Togglable.jsx look like this:
import { useState } from "react";
export const Togglable = ( props ) => {
const [visible, setVisible] = useState(false);
const hideWhenVisible = { display: visible ? "none" : "" };
const showWhenVisible = { display: visible ? "" : "none" };
const toggleVisibility = () => {
setVisible(!visible);
};
return (
<div>
<div style={hideWhenVisible}>
<button onClick={toggleVisibility}>{props.buttonLabel}</button>
</div>
<div style={showWhenVisible}>
{props.children}
<button onClick={toggleVisibility}>cancel</button>
</div>
</div>
);
});
The toggleVisibility function is called when props.buttonLabel in my case, "Sign in", is clicked or when "cancel" is clicked.
Demonstrated here:
