This segment covers๐ You can read the text in 6 minutes. Solving the exercises might take longer.
To learn about React components, we're going to build the first part of our static ticket list app โย the individual ticket.
We're going to do a code-along. ๐
You can see the finished app on Github.
React components come in two flavors:
A title component might look like this ๐
class Title extends Component {
render() {
return <h1>{this.props.title}</h1>
}
}
ReactDOM.render(<Title title="Hello world" />, document.getElementById('root'))
Class components get all of React's features:
But writing all of that gets tedious, if all you want is to render a few elements. So you can use functional stateless components instead ๐
const Title = ({ title }) => <h1>{title}</h1>;
ReactDOM.render(<Title title="Hello world" />, document.getElementById('root'))
Same result, a lot less typing.
Stateless components keep props, but lose state and lifecycle hooks. In return they have smaller overhead and are quicker to write.
Using our Title
component is kind of tedious. We can make it better with React's magic children
prop.
const Title = ({ children }) => <h1>{children}</h1>;
ReactDOM.render(<Title>Hello world</Title>, document.getElementById('root'))
We're still saying Title
twice, but this way feels more natural.
Component children are passed into every component as props. You can do with them as you please.
Components behave just like custom HTML elements. You can nest them, you can pass them around, you can do whatever you want.
React 16 introduced fragments โย components that render children, but take themselves out of the DOM. Before React 16, we often had to wrap elements in unnecessary <div>
s that made final markup look convoluted.
With Fragments, we can now return arrays of components. The actual <React.Fragment /โฅ
component makes returning an array more idiomatic.
const DecayOfLying = () => (
<React.Fragment>
<p>If Nature had been comfortable, mankind would never have invented architecture...In a house, we all feel of the proper proportions. Everything is subordinated to us, fashioned for our use and our pleasure.</p>
<p>It is always the unreadable that occurs.</p>
<p>His style is chaos illumined by flashes of lightning.</p>
<p>A reference to George Meredith's style.</p>
<p>Life imitates art far more than art imitates Life.</p>
<p>No great artist ever sees things as they really are. If he did, he would cease to be an artist.</p>
<p>The final revelation is that Lying, the telling of beautiful untrue things, is the proper aim of Art.</p>
</React.Fragment>
);
React 16.2 introduced the new <> ... </>
syntax, which is easier to type. However it is not yet supported by large parts of the ecosystem.
Build a placeholder <Ticket />
component.
When you're building apps with React, you want to make sure information always flows in one direction. You should always have a single source of truth, which sends information down to components via props, and accepts updates through callbacks or global actions.
More on that later.
For now just keep in mind that your component should always be able to render itself from props. Avoid relying on state whenever possible.
When you do need state, you should drive it through React's built-in state management (or Redux/MobX, but that's next week).
You can think of state as props that change over time.
You drive the change through calling this.setState
on your class-based component.
class Counter extends React.Component {
constructor() {
super();
this.state = {
N: 0
}
}
onClick() {
this.setState({
N: this.state.N + 1
});
}
render() {
return (
<button onClick={this.onClick.bind(this)}>{this.state.N}</button>
)
}
}
Calling setState
updates the component's this.state
object and triggers a re-render. Yes, you re-render on every state change. That's the beauty of React.
Use real data in your <Ticket />
component.
Add a click handler to your <Ticket />
that increases how many you're trying to get.
One of my favorite features of React's class-based components are their lifecycle hooks. You can think of them as callbacks for key events in a components lifecycle.
The best way to explain these is through a diagram and lots of hand waving.
[draw diagram on whiteboard]
It's time to make our list of tickets. We have a couple of options ๐
styleName
propI'll explain all four, then we'll use styled components because I think they're the best compromise between ease of use and transferable skills from the old times.
div {
background: pink;
}
<div style={{background: 'pink'}} />
๐ great for giving each rectangle a different color
.bg-pink {
background: pink;
}
import CSSModules from 'react-css-modules';
import styles from './index.css';
<div styleName="bg-pink"
import styled from 'styled-components';
const Div = styled.div`
background: pink;
`
<Div ... />
Personally I like styled components and I often use the style
prop for one-off styling. The community doesn't seem to have reached consensus on which approach is best.