-
-
Save RebootJeff/125fa7ebb9d440e07a3a3602e3ef64db to your computer and use it in GitHub Desktop.
.foo { | |
margin: 10px; | |
} | |
.banner { | |
padding: 10px; | |
text-align: center; | |
} | |
.error { | |
background-color: red; | |
} | |
.warning { | |
background-color: yellow; | |
} | |
.confirmation { | |
background-color: green; | |
} |
// Consider making this a functional component unless you really need it to be a class component | |
class Foo extends Component { | |
render() { | |
let type; | |
let message; | |
if(error) { | |
type = 'error'; | |
message = error.message; | |
} else if(1 === 2) { | |
type = 'warning'; | |
message = 'Something REALLY weird is happening?!'; | |
} else { | |
type = 'confirmation'; | |
message = 'Your dog was succesfully fed through our app'; | |
} | |
return (<div className="foo"> | |
<Banner type={type}>{message}</Banner> | |
{/* ...and other stuff to render within the same div.foo */} | |
</div>); | |
} | |
} | |
// Hi! I'm a "functional component" because I'm just a function that happens to accept `props` and return some JSX. | |
const Banner = (props) => { | |
const { type, message } = props; | |
return (<div className={'banner ' + type}> // the type helps defines the styling via CSS | |
<h2>{message}</h2> | |
</div>); | |
}; |
Line 5 is helpful. In a case like this, I wasn't sure whether to use let at the beginning or const in each if block.
const
in each if
block wouldn't actually work. Both const
and let
are block-scoped whereas var
is function-scoped (lexical). In other words, you have no choice 😝
This is basically what the code currently looks like.
Ok that's fine. But creating the 3 different possible views should be done with separate functions (ideally 3 different React components) or separate methods (see below).
// option 1 (cleaner)
render() {
if(/* error */) {
return <ErrorMessage error={error} />;
}
if(/* special case */) {
return <SpecialCaseComponent />;
}
return (
// the form
);
}
// option 2 (faster, but file length grows quickly)
_renderError(error) {
// has access to `this.props` and `this.state`
// returns some JSX
}
_renderSpecial() {
// ...
}
_renderForm() {
// ...
}
render() {
if(/* error */) {
return this._renderError(error);
}
if(/* special case */) {
return this._renderSpecial();
}
return this._renderForm();
}
when should I use these vs. making it a class component?
Functional components are dead simple functions that have access to React component props
and nothing else. You usually use them to create "dumb/presentational components" that have no major logic. You give them click handlers, data to render, etc as props. But they don't define their own event handlers and whatnot.
Class components have access to props
, state
, React lifecycle methods such as componentDidMount
, refs
, etc. They are more powerful. You usually use them to create "smart/stateful containers". If you use Redux, then class components are the ones that actually get wired up with Redux stuff. As the term "smart container" implies, they often define event handlers, interact with Redux state/actions (or normal React state
if you have no state management library like Redux), etc. They often render functional components rather than directly rendering any HTML themselves (except for maybe wrapping <div>
s because every React component must return a single node, so you might have to wrap stuff into a single <div>
).
If using the classic MVC paradigm... you can kinda think of class components as being controllers, but frameworks like React prefer to avoid analogies to MVC altogether. It's a whole new world!
Guideline: Use functional components as much as possible. Only use class components if you need to access this.state
, lifecycle methods, etc. When using class components, try to have them render as little HTML as possible by having them render functional components. The functional components then handle the nitty gritty of HTML. Of course functional components can render more React components as children, but the point is that "smart containers" aren't concerned with presentation so much as they are concerned with wiring up events, actions, state, etc.
There's a lot more to the class than I described to you. I'm not writing it, I'm fixing a bug in it and trying to address style comments in my PR review.
let
at the beginning orconst
in eachif
block.