Bonjour,
Today, I will try to demonstrate a concept of microservice in react js. We all know that Cloud Microservice Architecture is the favorite architecture of many developers these days. One of the popular examples in production with monthly traffic of 387.17M (Oct, 22) is "Netflix". My example is just a small widget, nothing compared to Netflix of course.
I am going to clone a sidebar widget of NY times.
Steps 1
For this just create a new react app using this command
npx create-react-app ny-times-microservice-widget-clone
Now, download some packages
npm i axios
npm i parcel
Then add the following code in the package.json file.
"build:widget": "parcel build src/index.js --no-source-maps --dist-dir widget",
Now let's start some coding :)
Steps 2
- Create a folder components inside the src folder.
- Create a new file inside named PostsWidget.jsx
- Write the following lines of code.
const PostsWidget = () => {
return (
<section>
<div>
<h3>Tags</h3>
<h3>This is a title</h3>
<p>1 Reactions</p>
</div>
</section>
);
};
export default PostsWidget;
Here we just created a component that will render two headings and one paragraph at the front-end. Let's add some styling (Note: all styling is copied from NY Times).
- Create a new file inside components folder named PostsWidget.module.css
.storyWrapper{
border-bottom: 1px solid #dfdfdf;
padding: 16px 0px
}
.subHeading{
color: #727272;
font-size: 0.6875rem;
font-weight: 700;
text-transform: uppercase;
line-height: 1.35em !important;
letter-spacing: 1px !important;
margin-bottom: 0.25rem;
}
.mainHeadind{
color: #121212;
font-size: 1.375rem;
line-height: 1.2em;
letter-spacing: 0.01em;
font-weight: 700;
-webkit-font-smoothing: antialiased;
margin: 0;
}
.reactions{
color: #727272;
font-size: 0.625rem;
line-height: 1.25em;
letter-spacing: 0.1em;
text-transform: uppercase;
margin: 0;
margin-top: 0.25rem;
}
import styles from "./PostsWidget.module.css";
...
<h3 className={styles.subHeading}>Tags</h3>
<h3 className={styles.mainHeadind}>This is a title</h3>
<p className={styles.reactions}>1 Reactions</p>
...
Steps 3
API integration, I am using dummyjson.com for dummy data.
const [articles, setArticles] = useState([]);
...
useEffect(() => {
axios
.get(`https://dummyjson.com/posts?skip=0&limit=5`)
.then(function (response) {
console.log("response", response?.data);
setArticles(response.data);
})
.catch(function (error) {
setError("error");
});
}, [limit, skip]);
...
Step 4
A div with data attributes to pass props and render this widget.
<div class="post-widget" data-skip="0" data-limit="5"></div>
Step 5
Targeting this div and passing props to our component. Go to src/index.js. Now, we'll use a JavaScript selector (querySelectorAll) to target the div. Then we will loop through it so we can render this widget as many times as we want on the same page.
...
import PostsWidget from './components/PostsWidget.jsx';
const widgets = document.querySelectorAll('.post-widget')
widgets.forEach(widget => {
ReactDOM.render(
<React.StrictMode>
<PostsWidget widget={widget} />
</React.StrictMode>,
widget
);
})
...
Then, get this prop inside component and passing it to API endpoint.
...
const PostsWidget = ({ widget }) => {
const skip = widget.getAttribute("data-skip") || 0;
const limit = parseInt(widget.getAttribute("data-limit") ?? 5);
...
const [error, setError] = useState(false);
useEffect(() => {
axios
.get(`https://dummyjson.com/posts?skip=${skip}&limit=${limit}`)
.then(function (response) {
console.log("response", response?.data);
setArticles(response.data);
})
.catch(function (error) {
setError("error");
});
}, [limit, skip]);
if (error) {
return <div>{error}</div>;
}
now map all the articles
...
{articles?.posts?.map((article) => {
return (
<div className={styles.storyWrapper} key={article.id}>
<h3 className={styles.subHeading}>{article?.tags?.toString()}</h3>
<h3 className={styles.mainHeadind}>
{article?.title}
</h3>
<p className={styles.reactions}>{article?.reactions} Reactions</p>
</div>
);
})}
...
Step 6
Build, a normal react build will create multiple static files but we need a single file for JavaScript and CSS to target this widget. For this purpose, we install Parcel at the start. Let's create a build using this package.
yarn build:widget
Step 7
Host your widget somewhere. For learning purposes, I've served this build locally and used it inside an HTML file to show you guys.
...
<link rel="stylesheet" href="http://192.100.00.00:3000/index.css">
....
<body>
<div class="post-widget" data-skip="0" data-limit="5"></div>
<script src="http://192.100.00.00:3000/index.js"></script>
</body>
...
You can find the complete code here. My vscode directory before the build.
My vscode directory after the build.
NY times widget for reference
This is how react widget will look.
What if we need only the JS link and HTML div, no CSS link
Yes, we can do it. just need to add another hook. Go to your PostWidget.js file and write following code
useEffect(() => {
const fetchCSS = async () => {
try {
const response = await axios.get('http://192.100.00.00:3000/index.css');
const style = document.createElement('style');
style.textContent = response.data;
document.head.appendChild(style);
} catch (error) {
console.error(error);
}
};
fetchCSS();
}, []);
This hook will add your CSS code in the head direct. This is one way of doing it, not sure which one is better. Let me know your opinion in the comments.
If you find this standalone react app (microservice) helpful then please like ❤ and share it with your friends, follow me on LinkedIn for more helpful resources.
Top comments (0)