React Components: Difference between revisions
Line 89: | Line 89: | ||
* Context | * Context | ||
Context in React is used to share data that is global to a component tree such as an authenticated user or preferred theme without passing that data as props. | Context in React is used to share data that is global to a component tree such as an authenticated user or preferred theme without passing that data as props. | ||
==Simple Example of HOC== | ==HOC== | ||
===Simple Example of HOC=== | |||
As specified above a HOS is a function that takes a component and returns a new component | As specified above a HOS is a function that takes a component and returns a new component | ||
<syntaxhighlight lang="js"> | <syntaxhighlight lang="js"> |
Revision as of 04:34, 4 December 2020
Designing Components
Resources
These can found here https://github.com/pkellner/pluralsight-designing-react-components-course-code Implements
- Component Reuse
- Single Responsibility
- Dont Repeat Yourself
Next JS Setup
Create project with
npm install react react-dom next --save
Add three commands to packages.json
"dev": "next",
"build": "next build",
"start": "next start"
Basic Page
In the demo the tutor builds an app which looks like this
With next js we can create a basic page using images to represent components
function Page() {
return (
<div>
<img src="images/header.png" />
<img src="images/menu.gif" />
<img src="images/searchbar.gif" />
<img src="images/speakers.png" />
<img src="images/footer.png" />
</div>
)
}
export default Page
Replacing with Components
To start making our components we can replace the images with components. For example
import React from 'react'
const Header = () => <img src="images/header.png" />
export default Header
And replace the Page with the components i.e.
function Page() {
return (
<div>
<Header />
<Menu />
<SpeakerSearchBar />
<Speakers />
<Footer />
</div>
)
}
export default Page
Breaking Down Futher
We can now break down further the speaker image into individual speakers.
const Speakers = () => {
const speakers = [
{ image: "images/speaker-component-1124.png", name: "a" },
{ image: "images/speaker-component-1530.png", name: "b" },
{ image: "images/speaker-component-10803.png", name: "c" },
];
return (
<div>
{speakers.map((x) => {
return <img src={x.image} alt={x.name} key={x.image} />;
})}
</div>
);
};
export default Speakers;
Component Abstractions
In programming three patterns used to abstract
- HOC - Higher Order Component
A higher-order component is a function that takes a component and returns a new component
- RP - Render Prop
A RP is simply a prop that takes a function which returns elements that will be used in render(). You can pass an element directly into a prop and use it in render() which would make the whole thing a RP by name, but generally, when people speak about RPs, they mean the first definition.
- Context
Context in React is used to share data that is global to a component tree such as an authenticated user or preferred theme without passing that data as props.
HOC
Simple Example of HOC
As specified above a HOS is a function that takes a component and returns a new component
const EnhancedSpeakerComponent = withData(Speakers)
function withData(Component) {
return function() {
return <Component />
}
}
export default EnhancedSpeakerComponent
Move the Data to HOC
Now lets move our array into the HOC to have
const EnhancedSpeakerComponent = withData(Speakers)
function withData(Component) {
const speakers = [
{ image: "images/speaker-component-1124.png", name: "a" },
{ image: "images/speaker-component-1530.png", name: "b" },
{ image: "images/speaker-component-10803.png", name: "c" },
]
return function() {
return <Component speakers={speakers} />
}
}
export default EnhancedSpeakerComponent
And change the component to have speakers as a prop
const Speakers = ({speakers}) => {
return (
<div>
{speakers.map((x) => {
return <img src={x.image} alt={x.name} key={x.image} />;
})}
</div>
);
};
We can now put the withData in a separate function and import into the Speakers component so we now have.
import React from 'react'
import withData from './withData'
const Speakers = ({speakers}) => {
return (
<div>
{speakers.map((x) => {
return <img src={x.image} alt={x.name} key={x.image} />;
})}
</div>
);
};
export default withData(Speakers)
Adding Parameter to Our HOC
Lets say we want to limit the number of images. We can do this but passing a value to the function like below
const maxSpeakersToShow = 2
export default withData(maxSpeakersToShow)(Speakers)
This is very similar to how we implement decorators in python, java or other languages because to implement this in the function we simply wrap the function and return it
function withData(maxSpeakersToShow) {
return function(Component) {
...
}
}
Here is the full example.
import React from "react";
function withData(maxSpeakersToShow) {
return function(Component) {
const speakers = [
{ image: "images/speaker-component-1124.png", name: "a" },
{ image: "images/speaker-component-1530.png", name: "b" },
{ image: "images/speaker-component-10803.png", name: "c" },
];
return function () {
const limitSpeakers = speakers.slice(0, maxSpeakersToShow)
return <Component speakers={limitSpeakers} />;
};
}
}
export default withData;
Let use the more modern format with lambdas.
const withData = (maxSpeakersToShow) => (Component) => {
const speakers = [
{ image: "images/speaker-component-1124.png", name: "a" },
{ image: "images/speaker-component-1530.png", name: "b" },
{ image: "images/speaker-component-10803.png", name: "c" },
]
return () => {
const limitSpeakers = speakers.slice(0, maxSpeakersToShow);
return <Component speakers={limitSpeakers} />;
}
}