A Musician's Guide to React
Stephen Carter
Posted on March 8, 2023
Intro
As the title suggests, this post aims to provide an overview of React to musicians learning code. Perhaps you too are a musician making the career switch to development. I have heard that I am far from alone in this respect. If so, allow me to analogize React with familiar music and tech terms. Now before we get into Verse 1, let's start with a question:
What is React?
Built by FaceBook engineers, React is technically a JS library but often called a framework. It's like arguing over enharmonic tones. Is that really an Ab or a G#? Of course, there is a correct answer, but no matter what you call it, both tones sound the same. So library or framework, React organizes and simplifies JS by using a declarative approach to coding.
Declarative programs write the desired outcome and leave the specifics of how to the computer. It's the difference between a bare-bones chord chart and a highly orchestrated symphony. The chord chart is declarative, it doesn't specify how to voice the C chord, just that the end result is in fact a C chord.
Verse 1: Components
Components are where the magic of React begins. Components are reusable bits of code. It's like a chord progression that gets used in every verse. The lyrical content changes, but the musical structure stays the same.
Think of any web-app you use (Instagram, FaceBook, Planning Center). The data that's displayed is specific to you, but the way the data is displayed is consistent with every user.
Components use the single responsibility principle. They can be as simple as a button or as large as a container that organizes the other components. Think of it as an electric guitar setup. Each pedal on the board modifies the sound of the guitar in one specific way. Each pedal is a component. The board is also a component. It doesn't modify the sound at all, but it holds each of the other components in place allowing them to be organized and connected.
Speaking of connecting components, with sound equipment, you connect the inputs and outputs with cables. In React components, we use imports and exports.
// src/components/Button.js
// To use React in a component file, import it.
import React from 'react';
// Component functions begin with a capital letter.
// The capital letter distinguishes a React component from a vanilla JS function.
function Button() {
return (
<button>Click Me!</button>
);
}
// To use this component elsewhere, export it.
export default Button;
Once we have a component with an export, we can import it for use in any other component.
// src/components/App.js
import React from 'react';
// import the Button component to use in the App component.
import Button from './Button';
// Components can only return one element.
// Since we want three buttons, we wrap them in a div.
function App() {
return (
<div>
<Button />
<Button />
<Button />
</div>
);
}
export default App;
So this App component will display three button components when rendered. Now you may be wondering, "What is HTML doing inside JS?" π€
JSX
React introduces a JS eXtension syntax called JSX. JSX is a hybrid of HTML and JS. Since React is declarative, the code declares the desired outcome. In the example above, a <button>
is declared. The HTML-style tags make the code visually appealing, but since this is JSX, we can use JS easily inside the tags with curly braces {}
.
const text = "Click Me!"
function Button() {
return (
<button>{text}</button>
);
}
While this button component renders the same as the prior one, the text of the button has been abstracted and can be changed through the text
variable.
function Button() {
return (
<button>{signIn ? "Sign Out" : "Sign In"}</button>
);
}
Here, a ternary expression uses a signIn
variable to determine the text of the button. If signIn
is true, the button displays "Sign Out" as the text. Otherwise, the button displays "Sign In" as the text. The same button is used for signing in and out simplifying the code.
Now, what if we want to use the Button component for more than two different options? Since the whole idea of components is to be reusable, there must be a way to abstract the button text even further. And if you think the answer is yes, props to you. ππ Let's go to Verse 2!
Verse 2: Props
Props (short for properties) are the way we send information down from parent components to child components. In our pedal board example, the board is the parent component and the pedals are the children components. The analogy falls short in this case because the pedal board does not send any information to the pedals. But we can think of it like signal flow. The guitar produces a signal that is sent down to the pedals and then on to the sound system.
In the example below the App component is the parent of the Button components. The Button components are children of App and siblings to each other.
In order to display different messages in each button, we pass along a prop called buttonText
with differing values for each Button.
function App() {
return (
<div>
<Button buttonText="Click Me!" />
<Button buttonText="π" />
<Button buttonText="π" />
</div>
);
}
Props are given to the component as an argument in curly braces.
function Button({ buttonText }) {
return (
<button>{buttonText}</button>
);
}
This feature provides the ability to have highly abstracted, customizable components.
Inverse Flow
Since props only flow from parent to child, you can imagine there are problems when one child has data that another child needs. Maybe a Form component collects data to be displayed later in a Dashboard component. In such cases, we can pass a function down as a prop and call that function within the child component along with arguments that then inverse the flow of data within the app.
Chorus: State
State is the ability to store dynamic data in React apps. Updating State with new data will cause the component to re-render. This allows us to display updated information without having to refresh the page. It also speeds up the user experience since we don't have to keep going back to the server for information. We keep all of that information client-side with State.
Hook: React Hook
What is a chorus without a good hook? To use State we first import a React Hook called useState
. The useState
hook allows us to "hook" into React's internal state. (Many other React Hooks exist besides useState
including the option of writing custom hooks.)
// useState is an internal variable in React.
// Variables are imported with curly braces.
import React, { useState } from 'react';
We tell React to create State for a component through an array of two variables. The naming convention for these variables is state
and setState
.
import React, { useState } from 'react';
const studentRoster = [
{ name: "Tom", lesson: "Piano" },
{ name: "Leslie", lesson: "Voice" },
{ name: "Harry", lesson: "Cello" },
];
function App() {
const [students, setStudents] = useState(studentRoster);
// ...
}
Once State is set, we can write any number of functions to manipulate the data. In the above example, we can write functions to display each student and lesson type on a card. Then, we could write a sort feature to display the student cards alphabetically. Or we could write a filter feature that only displays students with a certain type of lesson. The power of this feature is immense.
Now in order to update the value of State, we need to talk about Events.
Bridge: Events
Similar to the addEventListener() method in JS, Events provide functionality within React. Events use props beginning with on
: onClick
, onHover
, onSubmit
, etc. In the example below, onClick
is passed with a value of handleClick
which is a function defined within the component.
function Button() {
function handleClick() {
console.log('That was easy!');
}
return (
<button onClick={handleClick}>Easy</button>
);
}
Events are useful for updating State.
import React, { useState } from 'react';
function PlayButton() {
const [play, setPlay] = useState(false)
function handleClick() {
setClicked(!play);
}
return (
<button onClick={handleClick}>
{play ? 'Play' : 'Pause'}
</button>
);
}
In the example above, the component PlayButton
uses State to determine the button's text. It uses a prop onClick
to update the state which causes the component to re-render with a new message based on the change in state.
Since our handleClick
function is so short, we can refactor the button with an anonymous arrow function.
import React, { useState } from 'react';
function PlayButton() {
const [play, setPlay] = useState(false)
return (
<button onClick={() => setClicked(!play)}>
{play ? 'Play' : 'Pause'}
</button>
);
}
Now we have a PlayButton toggle component that can be used for a music app.
Ending
Components, props, state and events, these are four of the big ideas in React. Now that you have a basic overview from a musician's perspective, take a deep dive in the official React Docs.
Credit
Photo by Anton Shuvalov on Unsplash
Posted on March 8, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.