React Components
What is a React Component?
A React component is a JavaScript function that you can 'sprinkle' with markup.
Can be as small as a button.
Can be as big as an entire page.
You can also have a parent component that renders (multiple) child components.
You can pass information to your own components, this is called props.
Different Types of Components
There are two different types of components within React.
Smart Component
Seen as a home page
Something you want to save on application-level
DOM Component
Gets information from the Smart Component
Defining Components
How to Build a Component
There are multiple steps to building and defining a component.
One: Export a component
There is a standard JS prefix `export default` for exporting your component.
This prefix lets you mark a main function in a file that you can then import in to other files, so that you can actually use the component throughout your other code.
Two: Defining the function
React components are actually regular JavaScript functions, but their names have to start with a capital letter. This would mean that instead of function profile() {}
, you'd have to call it function Profile() {}
.
Three: Adding Markup
Even if your component returns 'regular' html tags, it is actually JSX, which is JavaScript under the hood.
A return statement can then be written like so:
<img src="https://something.com" alt="Something" />
Quick Tip: If your return statement consists of more than one line, should put the code in between of parentheses ()
. Otherwise, they will be ignored.
Exporting and Importing a Component
If you want to use a component somewhere, it can make sense to remove the component out of the root component file. This root component file is where the root file is living. This can be App.js
but can also be different.
It's a good idea to create a new JS file where you can put your components. Afterwards, you can export that function component from that file and import it in to the file that you will use the component in.
Props
What are Props?
Props are information that you pass to a JSX tag. These are things like className
, src
, alt
, etc
They are basically just variables that come in to your project.
How to pass props to a component
One: Pass Props to a child component
export default function Profile() {
return (
<Avatar
person={{ name: 'Iris', imageId: 'b4id8eha' }}
size={100}
/>
)
}
function Avatar({ person, size }) {
// person and size are available here
}
Two: Read the Props inside of the child component
Once you have done both steps, you can do the following:
You can add logic to the component for rendering.
You can configure the component to render it in many different ways with different props.
Giving a Prop a default value
You can give a prop a default value very easily, inside of the curly braces of the function.
function Avatar({ person, size = 100 }) {
// ...
}
Forwarding Props with Spread
It can be quite repetitive to constantly pass props.
There happens to be a components that forwards all their props to their children.
The components can do this by spreading their props using the three dots.
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
)
}
In this example, the code is forwarding all the props of the profile component to the avatar component, and this is done without listing all the names.
You should use this with restraint. If you have to use it in every component, you're doing something wrong.
A few notes
Props are not always static, they can change over time.
Props are immutable, which means they cannot be changes.
So, when a component needs to change its props (like as a response to a user interaction or new data), it will have to ask its parent component to pass it different props, like a new object.
Old props will be cast aside.
You should not try to change props, you can use set state.
Keeping Components Pure
What is a pure function?
A pure function can only perform a calculation and nothing more. You can avoid classes, bugs and unpredicted behavior as your codebase grows by writing you components as pure functions.
Characteristics of a pure function
It minds its own business: it does not change any objects or variables that existed before it was called.
Same inputs, same output: a pure function should always return the same result as the input it was given.
React assumes that every component you write is a pure function and is therefore designed around this concept.
Side effects of pure functions
Since React's rendering process must always be pure, you should always let components return their JSX, but not change any objects and variables that already existed before rendering, since that would make them impure.
Instead of reading and writing a `guest` variable declared outside of the pure function, you can pass `guest` as a prop instead.
Local Mutation
A mutation is seen as changing a preexisting variable while rendering.
Pure functions do not mutate variables outside of the function's scope or objects that were created before the call (since that will make them impure).
It is fine to change variables and objects that you have created while rendering.
Example:
function Cup({ guest }) {
return <h2>Tea cup for guest #{guest}</h2>
}
export default function TeaGathering() {
let cups = []
for (let i - 1; i <= 12, i++) {
cups.push(<Cup key=[i] guest=[i] />
}
return cups
}
Are side effects ever okay?
Side effects can be needed changes, like starting an animation, changing the data. They happen on the side and not during the rendering.
Usually, side effects belong inside event handlers. These are functions that React runs when you perform some action, like when you click a button.
Even though event handlers are defined inside of your component, they do not run during rendering. Event handlers therefore do not need to be pure.
External sources
Old React documentation about components and props