Working with React-bootstrap Buttons
Dec 27, 2019 • 9 Minute Read
Introduction
Buttons are one of the most commonly used components in a client-side application. Having custom buttons in your design system is pretty much a necessity.
One of the most popular component libraries on the market, Bootstrap, has you covered with button components. Bootstrap provides tons of options for customizing buttons to your own needs. The one caveat is that Bootstrap relies on jQuery for functionality. If you are building an application in React, you need something that works without jQuery. That's where react-bootstrap comes in.
In this guide, I show you how to use the button component from the react-bootstrap library to add fully customized, reusable buttons to your react application.
Installation
Getting started with react-bootstrap is simple. You just need to add the Bootstrap and react-bootstrap packages from npm:
yarn add bootstrap react-bootstrap
# or
npm i bootstrap react-bootstrap
To make sure your buttons are utilizing the Bootstrap CSS, you need to import that into your application, along with the button component.
import React from 'react';
import Button from 'react-bootstrap/Button';
import 'bootstrap/dist/css/bootstrap.min.css';
...
Now we can start using our buttons:
import React from 'react';
import Button from 'react-bootstrap/Button';
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
return (
<form>
<label htmlFor='username'>Username</label>
<input id='username' />
<Button type='submit'>Submit</Button>
</form>
);
};
Buttons don't have to be used only to submit a form. We can use buttons as checkboxes or radio options as well. An example of a list of checkbox options using buttons would look like this:
import ToggleButtonGroup from 'react-bootstrap/ToggleButtonGroup';
import ToggleButton from 'react-bootstrap/ToggleButton';
const App = () => {
return (
<form>
<label htmlFor='name'>Name</label>
<input id='name' />
<label htmlFor='genre'>Favorite genre of music</label>
<ToggleButtonGroup type='checkbox' name='genre'>
<ToggleButton value={'hip_hop'}>Hip Hop</ToggleButton>
<ToggleButton value={'jazz'}>Jazz</ToggleButton>
<ToggleButton value={'country'}>Country</ToggleButton>
</ToggleButtonGroup>
<Button type='submit'>Submit</Button>
</form>
);
};
Here I'm using some components that make it easier to deal with multiple buttons. The ToggleButtonGroup component is used to group form components where each ToggleButton is an option in that group. ToggleButtonGroup takes a name attribute, which is like the name on an <input />. Each ToggleButton takes a value attribute, which works like <input value={..}>. If we need to pre-check any of the checkboxes, we accomplish that with the defaultValue property:
const App = () => {
return (
<form>
<label htmlFor='name'>Name</label>
<input id='name' />
<label htmlFor='genre'>Favorite genre of music</label>
<ToggleButtonGroup
type='checkbox'
name='genre'
defaultValue={['hip_hop', 'jazz']}
>
<ToggleButton value={'hip_hop'}>Hip Hop</ToggleButton>
<ToggleButton value={'jazz'}>Jazz</ToggleButton>
<ToggleButton value={'country'}>Country</ToggleButton>
</ToggleButtonGroup>
<Button type='submit'>Submit</Button>
</form>
);
};
The same would work with radio buttons, except you would have only one option pre-selected:
const App = () => {
return (
...
<ToggleButtonGroup
type='radio'
name='genre'
defaultValue={['jazz']}
>
<ToggleButton value={'hip_hop'}>Hip Hop</ToggleButton>
<ToggleButton value={'jazz'}>Jazz</ToggleButton>
<ToggleButton value={'country'}>Country</ToggleButton>
</ToggleButtonGroup>
<Button type='submit'>Submit</Button>
...
);
};
Controlled States
Using React to control the state of form inputs is widespread. Controlling the state means a state variable holds the value of an input within a React component. There's not anything special you need to do in a react-bootstrap component to make this work. You need to create a state property on your component, and you need to create a function that updates the state's value when the form input changes.
const App = () => {
const [genre, setGenre] = React.useState();
const handleGenreChange = (selectedValue) => {
setGenre(selectedValue)
}
return (
...
<ToggleButtonGroup
type='checkbox'
name='genre'
value={genre}
onChange={handleGenreChange}
>
<ToggleButton value={'hip_hop'}>Hip Hop</ToggleButton>
<ToggleButton value={'jazz'}>Jazz</ToggleButton>
<ToggleButton value={'country'}>Country</ToggleButton>
</ToggleButtonGroup>
<Button type='submit'>Submit</Button>
...
);
};
Loading State
We can also add a loading state to our buttons. Adding a loading state is helpful when we need to make a network request when a user clicks a button. We want to make sure they can only click the button once while the network waits to respond.
const App = () => {
const [isLoading, setIsLoading] = React.useState(false);
React.useEffect(() => {
if (isLoading) {
fetch('http://someAPI')
.then(response => response.json())
.then(success => {
setIsLoading(false);
})
.catch(e => {
setIsLoading(false);
});
}
}, [isLoading]);
const submitForm = () => {
setIsLoading(true);
};
return (
<form>
<label htmlFor='name'>Name</label>
<input id='name' />
<label htmlFor='genre'>Favorite genre of music</label>
<ToggleButtonGroup type='checkbox' name='genre'>
<ToggleButton value={'hip_hop'}>Hip Hop</ToggleButton>
<ToggleButton value={'jazz'}>Jazz</ToggleButton>
<ToggleButton value={'country'}>Country</ToggleButton>
</ToggleButtonGroup>
<Button
type='submit'
disabled={isLoading}
onClick={!isLoading ? submitForm : null}
>
Submit
</Button>
</form>
);
};
Styled Buttons
Bootstrap gives you many default button variants to use, including primary, secondary, and success. The colors and styles of these variants can be updated by making a copy of the node_modules/bootstrap/scss/_variables.scss and putting the copy into your own src/ code. There you can update the SCSS variables for the color scheme as well as the button properties.
You can set the size of a button using the size property. The available options are sm or lg.
<ButtonToolbar>
<Button variant='primary' size='sm'>
Primary
</Button>
<Button variant='secondary' size='lg'>
Secondary
</Button>
</ButtonToolbar>
You can also set your button to span the full width of its parent using the block property. The value is a Boolean and defaults to false.
<ButtonToolbar>
<Button variant='primary' block={true}>
Primary
</Button>
</ButtonToolbar>
Here is a full list of the button variants that come with Bootstrap.
<ButtonToolbar>
<Button variant='primary'>Primary</Button>
<Button variant='secondary'>Secondary</Button>
<Button variant='success'>Success</Button>
<Button variant='warning'>Warning</Button>
<Button variant='danger'>Danger</Button>
<Button variant='info'>Info</Button>
<Button variant='light'>Light</Button>
<Button variant='dark'>Dark</Button>
<Button variant='link'>Link</Button>
/* Outline version of the main variants */
<Button variant='outline-primary'>Primary</Button>
<Button variant='outline-secondary'>Secondary</Button>
<Button variant='outline-success'>Success</Button>
<Button variant='outline-warning'>Warning</Button>
<Button variant='outline-danger'>Danger</Button>
<Button variant='outline-info'>Info</Button>
<Button variant='outline-light'>Light</Button>
<Button variant='outline-dark'>Dark</Button>
</ButtonToolbar>
Conclusion
Working with Bootstrap's buttons in a React application provides you with a robust set of components that can meet your design systems' needs. React-bootstrap provides easy-to-use properties for styling and adding functionality to your buttons. If you'd like to see more detailed documentation for react-bootstrap, visit the docs here.
Thanks for reading 😀