Reactjs global state

◾️ this is from udemy lecture for personal memo(go site)

◾️ STEP1 (create Data store)

import React, { createContext, useReducer } from "react";

const initialState = {
  popular: [],
  detail: {},
  side: [],
  search: [],
};

const reducer = (state, action) => {
  console.log(state, action);
  switch (action.type) {
    case "SET_POPULAR":
      // set popular var
      return { ...state, popular: action.payload.popular };
    case "SET_DETAIL":
      return { ...state, detail: action.payload.detail };
    case "SET_RELATED":
      return { ...state, side: action.payload.side };
    case "SET_SEARCH":
      return { ...state, search: action.payload.search };
    default:
      return state;
  }
};

export const Store = createContext({
  globalState: initialState,
  setGlobalState: () => null,
});

export const StoreProvider = ({ children }) => {
  // @SEE state / dispatch(call reducer)
  const [globalState, setGlobalState] = useReducer(reducer, initialState);
  return (
    <Store.Provider value={{ globalState, setGlobalState }}>
      {children}
    </Store.Provider>
  );
};

◾️ STEP2 (Context provider for accessing global data inside App component)

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { StoreProvider } from "./store/index";
import "normalize.css";

ReactDOM.render(
  <React.StrictMode>
    <StoreProvider>
      <App />
    </StoreProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

◾️ Usage of Global State

import React, { useEffect, useContext, useState } from "react";
import Layout from "../components/Layout/Layout";
import { youtubeApi } from "../apis/apis";
import { Store } from "../store/index";
import VideoGrid from "../components/VideoGrid/VideoGrid";
import VideoGridItem from "../components/VideoGridItem/VideoGridItem";
import Loader from "../components/Loader/Loader";
import Notice from "../components/Notice/Notice";

const Main = () => {
  const { globalState, setGlobalState } = useContext(Store);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const fetchData = async () => {
    try {
      const {
        data: { items },
      } = await youtubeApi.popularVideo();

      setGlobalState({ type: "SET_POPULAR", payload: { popular: items } });
    } catch {
      setError("fetch data error");
      setTimeout(() => {
        setError("");
      }, 2000);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchData();
  }, []);

  return (
    <Layout>
      <VideoGrid>
        {loading ? (
          <Loader />
        ) : (
          globalState.popular &&
          globalState.popular.map((item) => {
            console.log("each item", item);
            return (
              <VideoGridItem
                id={item.id}
                key={item.id}
                thumbnails={item.snippet.thumbnails.standard.url}
                title={item.snippet.title}
              />
            );
          })
        )}
        {error && <Notice message={error} />}
      </VideoGrid>
    </Layout>
  );
};

export default Main;

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です