Hey there, Quick Recap: yesterday we got a React app onto the screen, talked a bit about how JSX works a lot like HTML, and did a few tiny exercises. If you didn't go through yesterday's email -- that's fine, no judgment! Don't beat yourself up, don't feel guilty. We're all busy and I totally get it. To get the most out of this email though, you'll want to run through yesterday's first. If you can't find it, read it on the web here. Let's get into today's lesson: how to make your React components dynamic and reusable. Before we talk about how to do this in React, let's look at how to do this with plain functions. This might seem a bit basic but bear with me. Let's say you have this function: function greet() {
return "Hi Dave";
}
You can see pretty plainly that it will always return "Hi Dave". What if you want to greet someone else though? You'd pass in their name as an argument: function greet(name) {
return "Hi " + name;
}
Now you can greet anyone you want! Awesome. (I warned you this part was basic) Using Arguments in a React Component If you want to customize a React component, the principle is the same as customizing a function: pass an argument with your dynamic stuff, and then the component can change what it returns based on that stuff. Let's change the `Hi` component from yesterday to be able to say hi to whoever we want. If you still have the CodeSandbox tab open from yesterday, great -- if not, start with this one, and code along. Here's the original component: function Hi() {
return Hello World! ;
}
Add a parameter called "props", and replace World with {props.name} (which is a JS expression, remember - like we discussed yesterday): function Hi(props) {
return Hello {props.name}! ;
}
What's going on here? Well, first off, it just renders "Hello " because we're not passing a name yet. But aside from that... When React renders a component, it passes the component's props (short for "properties") as the first argument, as an object. The props object is just a plain JS object, where the keys are the prop names and the values are, well, the values of those props. You might now wonder, where do props come from? Glad you asked. Pass Props to a Component You, the developer, get to pass props to a component when it is invoked. And, in this app, we're invoking the `Hi` component in the last line: ReactDOM.render(, document.querySelector('#root'));
We need to pass a prop called "name" with the name of the person we want to greet, like this: ReactDOM.render(, document.querySelector('#root'));
With that change in place, the app now displays "Hello Dave!" Awesome! Here's a cool thing about props: you can pass whatever you want into them. You're not restricted to strings, or trying to guess what it will do with your string (*cough* Angular). Remember yesterday, and 30 seconds ago, how we put a JS expression inside single braces? Well, you can do the same thing with a prop's value:
This is how you can pass multiple props to a single component. Their values can be booleans, numbers, strings (as we saw), functions, and even objects. The object syntax looks a little weird ("what?? why are there double braces??"), but think of it as single braces surrounding an object literal, and you'll be alright.
Inside a component that receives multiple props, each one will be a separate property on the "props" object that's passed in. For example if we had a component called "HiFullName" that took two props, like this:
Then the internals of that component might look something like this: function HiFullName(props) {
return (
Hi {props.firstName} {props.lastName}!
);
}
All of that syntax, by the way, is React (specifically, JSX). It's not ES6 JavaScript. Which reminds me, I wanted to show you a couple bits of ES6 syntax that will make your components easier to write & read. A Few Bits of ES6 Most of the components you see in the wild will not take an argument called "props". Instead, they use ES6's destructuring syntax to pull the values out of the props object, which looks like this: function Hi({ name }) {
return Hello {name}! ;
}
The only thing that changed here is that the argument props became this object-looking thing { name }. What that says is: "I expect the first argument will be an object. Please extract the 'name' item out of it, and give it to me as a variable called 'name'." This saves you from having to write "props.whatever" all over the place, and makes it clear, right up top, which props this component expects. And you can accept multiple props by listing out the names inside the braces, like { firstName, lastName, age }. One more bit of ES6 syntax I want to show you, and then we're done. (Not to overload you with syntax or anything, but you'll probably see example code like this and I want you to be prepared for it.) This is const and the arrow function: const Hi = ({ name }) => {
return Hello {name}! ;
}
The const declares a constant, and the arrow function is everything after the first equal sign. Compare that code with the "function" version above. Can you see what happened? Here's the transformation step-by-step: // Plain function:
function Hi({ name }) {
return Hello {name}! ;
}
// A constant holding an anonymous function:
const Hi = function({ name }) {
return Hello {name}! ;
}
// Removing the "function" keyword and adding the
// arrow after the parameter list:
const Hi = ({ name }) => {
return Hello {name}! ;
}
// Optional step 3: Removing the braces, which makes the
// "return" implicit so we can remove that too. Leaving the parens
// in for readability:
const Hi = ({ name }) => (
Hello {name}! ;
)
// Optional step 4: If the component is really short, you can put
// it all on one line:
const Hi = ({ name }) => Hello {name}! ;
Your Turn Now you know how to pass props into a component to make it both dynamic and reusable! Work through these exercises to try out a few new things with props. (Remember: it's important to actually do the exercises!)
Tomorrow we'll look at how to make your app interactive, with React's state feature. Cheers, Dave |