DEV Community

Cover image for React Design Patterns~Container Componets / Loader Component~
Ogasawara Kakeru
Ogasawara Kakeru

Posted on

React Design Patterns~Container Componets / Loader Component~

・src/server.js

const express = require("express");

const app = express();

app.use(express.json());

let users = [
  {
    id: "1",
    name: "Smith",
   age: 30,
   country: "UK",
   magazines: ["VOGUE UK", "ID-MAGAZINE"],
  },
  {
    id: "2",
    name: "Kate",
   age: 31,
   country: "US",
   magazines: ["VOGUE US", "ELLE"],
  },
  {
    id: "3",
    name: "Josh",
   age: 32,
   country: "AUSTRALIA",
   magazines: ["VOGUE AU", "BAZAAR"],
  },
];

app.get("/users/:id", (req, res) => {
  const { id } = req.params;
  console.log(id);
  res.json(users.find((user) => user.id === id));
});

let SERVER_PORT = 8080;
app.listen(SERVER_PORT, () =>
  console.log(`Server is listening on port: ${SERVER_PORT}`)
);
Enter fullscreen mode Exit fullscreen mode

This file is server side with Express.js. Set this file under src folder.

・Install Express.js,executing command like "npm install express", if necessary.

・Execute this file with command like "node server.js".

・if "Server is listening on port: 8080" is diaplayed on the terminal,
the server is exected succesefuly.

・src/components/user-info.jsx

export const UserInfo = ({ user }) => {
  const { name, age, country, magazines} = user || {};
  return user ? (
    <>
      <h2>{name}</h2>
      <p>Age: {age} years</p>
      <p>Country: {country}</p>
      <h2>Books</h2>
      <ul>
        {magazines.map((magazine) => (
          <li key={magazine}> {magazine} </li>
        ))}
      </ul>
    </>
  ) : (
    <h1>Loading...</h1>
  );
};
Enter fullscreen mode Exit fullscreen mode

This component displays name, age, country and magazines as user infomation.

・src/components/data-source-with-render.jsx

import React, { useEffect, useState } from "react";

export const DataSourceWithRender = ({ getData = () => {}, render }) => {
  const [resource, setResource] = useState(null);

  useEffect(() => {
    (async () => {
      const data = await getData();
      setResource(data);
    })();
  }, [getData]);

  return render(resource);
};
Enter fullscreen mode Exit fullscreen mode

This component returns user information recieved as render props with user data as resource witch is fetched from users in server.js

・src/App.js

import axios from "axios";
import "./App.css";
import { UserInfo } from "./components/user-info";
import { DataSourceWithRender } from "./components/data-source-with-render";

const fetchData = async (url) => {
  const response = await axios.get(url);
  return response.data;
};

function App() {
  return (
    <>
      <DataSourceWithRender
        getData={() => fetchData("/users/1")}
        render={(resouce) => <UserInfo user={resouce} />}
      ></DataSourceWithRender>
    </>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This component returns DataSourceWithRender component passing getData and render as props.

GetData props is a function witch gets users datas using axios and returns them.

Render props is a function witch returns UserInfo components passing resource as props.

Image description

Top comments (0)