이메일 구독 응용 프로그램 구축 - 섹션 2: Zustand 연결

개술


이 강좌는 세 부분으로 구성되어 있으며, Zustand를 사용하여 구성 요소 단계에서 상태 관리를 하는 방법을 상세하게 소개할 것이다.Zustand를 전술적으로 사용하는 방법과 함께 완전히 통합된 React 구성 요소를 만드는 방법을 보여 드리겠습니다.
다음은 전체 시리즈에 포함될 내용을 세분화한 것입니다.
  • Part 1A: Creating a foundational React component
  • Part 1B: Adding a skeleton loader
  • Part 2: Connecting Zustand for fluid state management
  • Part 3: Connecting backend logic and microservice data resources
  • 경고로서, 편의를 위해, 위의 모든 부분은 코드 샌드박스에 연결되어 있으며, 이 부분의 완전한 코드를 포함한다.본 강좌를 공부할 때 시간을 충분히 이용하기 위해서, 우리는 이 절의 시작 부분의 단독 옵션 카드에서 부품의 모래상자를 열고 갈라놓는 것을 권장합니다.우리의 코드 샌드위치 예는 당신의 목표 환매일 수 있습니다.이 강좌의 모든 부분을 완성할 때, 목표는 최종적으로 목표와 비슷한 코드를 작성하는 것입니다.

    선결 조건


    이 섹션의 전제 조건은 Part 1과 같습니다.

    우리의 목표


    앞부분이 완고할 수도 있고 두통이 심할 수도 있으니 복잡성을 최대한 없애자.이 강좌의 이 부분에서, 우리는Zustand를 탐색하고 데이터 모델을 만들고, 저장하고, 그것들을 우리가 1부분에서 설정한 React 구성 요소에 연결할 것이다.

    시작: Zustand 개요


    조슈타인을 이해하다


    Zustand는 유연한 상태 관리 시스템이다.다음은 Zustand 작성자가 도구를 설명하는 방법입니다.

    “A small, fast and scaleable bearbones state-management solution. Has a comfy api based on hooks, isn't boilerplatey or opinionated, but still just enough to be explicit and flux-like. Don't disregard it because it's cute. It has quite the claws, lots of time was spent to deal with common pitfalls, like the dreaded zombie child problem, react concurrency, and context loss between mixed renderers. It may be the one state-manager in the React space that gets all of these right.”


    Zustand 설치


    Zustand 연결을 시작하려면 NPM 이 Zustand 를 설치해야 합니다.
    npm i zustand
    

    예비(fallback) 파일 생성하기


    Zustand를 사용하여 구성 요소의 내용을 동적으로 불러올 것입니다. 따라서 데이터를 불러올 때 의외의 문제가 발생하지 않도록 백업 내용을 사용할 수 있기를 바랍니다.이 백업 컨텐츠는 fallback.js 파일에 저장됩니다.src/components/email-block 폴더로 이동하여 여기에 fallback.js 파일을 추가합니다.파일을 생성한 후 다음 코드 세그먼트를 추가합니다.
    const content = {
      title: "Become smarter in just 5 minutes",
      subTitle:
        "Get the daily email that makes reading the news actually enjoyable. Stay informed and entertained, for free.",
      input: {
        id: "email-input",
        type: "email",
        label: "Email is required please",
        placeholder: "Enter your email",
        variant: "outlined"
      },
      errors: {
        invalidEmail: "We require a valid email",
        empty: "Email is required please"
      },
      button: {
        states: {
          initial: "Submit",
          processing: "Sending request",
          success: "Sent successfully",
          failed: "Failed! Try again."
        }
      }
    };
    
    export { content };
    

    구성 요소 상태 이해


    구성 요소의 상태에 따라 단추의 값을 제어할 것입니다.일단 저희 구성 요소가 불러오면 다음 네 가지 상태 중 하나일 수 있습니다 1) 초기 2) 처리 3) 성공 또는 4) 실패

    논리 폴더 추가

    src/components/email-block 폴더로 이동하여 논리 폴더를 만듭니다.이 폴더에는 data-models.js, flows.jsstore.js 파일이 생성됩니다.정결을 유지하기 위해서 이 세 문서는 반드시 독립적으로 존재해야 한다.현재 폴더 구조는 다음과 같습니다.

    우리의 두 데이터 모델을 만들다


    모델은 단지 우리가 전체 응용 프로그램에서 관리하기를 원하는 데이터에 불과하다.전문적인 선호로서 우리는 데이터 모델과 저장 구역을 분리하는 것을 좋아한다.이 응용 프로그램에 대해 우리는 두 개의 데이터 모델인 내용 모델과 불러오는 모델이 필요하다.
    내용 모델을 처리하는 것부터 시작하겠습니다. 제목, 부제목, 단추 텍스트를 책임집니다.모델에서는 다음이 필요합니다.
  • 콘텐츠
  • currentButtonText
  • setButtonText
  • getContent(동적 내용 획득용)
  • 콘텐츠 설정
  • src/components/logic/data-models.js 파일로 이동하여 다음 코드 세그먼트를 추가합니다.
    import { content } from "../fallback";
    
    const initContentModel = (set) => ({
      content,
      currentButtonText: content.button?.states?.initial,
      setButtonText: (buttonText) =>
        set((state) => ({ ...state, currentButtonText: buttonText })),
      getContent: () => {},
      setContent: (content) => {
        set((state) => ({ ...state, content }));
      }
    });
    
    export { initContentModel };
    
    
    이 코드에서, 우리는 initContentModel 함수를 만들어서, 우리가Zustand 상점을 조직하는 것을 도왔다.이 단계에서, 우리는 fallback.js 파일의 내용을 기본값으로 사용합니다.이 강좌의 뒷부분에서 동적 데이터로 변경할 것입니다.
    여기서 로드 모델에 대해 토론해 봅시다. 로드와 처리를 책임질 것입니다.서버에서 데이터를 요청할 때는 로딩을 사용하고 서버에 데이터를 보낼 때는 처리를 사용합니다.모델에서는 다음이 필요합니다.
  • 로드
  • 처리
  • 설정 로드
  • 순부하
  • 설정 처리
  • clearProcessing
  • 같은 src/components/logic/data-models.js 파일에서 다음 코드 세그먼트를 사용하여 파일을 확장합니다.
    import { content } from "../fallback";
    
    const initContentModel = (set) => ({
      content,
      currentButtonText: content.button?.states?.initial,
      setButtonText: (buttonText) =>
        set((state) => ({ ...state, currentButtonText: buttonText })),
      getContent: () => {},
      setContent: (content) => {
        set((state) => ({ ...state, content }));
      }
    });
    
    const initLoadingModel = (set) => ({
      loading: false,
      processing: false,
      setLoading: () => {
        set((state) => ({ ...state, loading: true }));
      },
      clearLoading: () => {
        set((state) => ({ ...state, loading: false }));
      },
      setProcessing: () => {
        set((state) => ({ ...state, processing: true }));
      },
      clearProcessing: () => {
        set((state) => ({ ...state, processing: false }));
      }
    });
    
    export { initContentModel, initLoadingModel };
    
    

    Zustand 스토어 만들기


    명확하게 보기 위해서, 다른 일을 하기 전에, 상점이 실제로 무엇인지 정의합시다.Zustand documentation에 따르면 상점은 단지 연결고리일 뿐이다.NPM 페이지의 세그먼트는 다음과 같습니다.

    이제 Zustand 스토리지를 만들고 이전에 생성한 데이터 모델을 추가합니다.이렇게 하려면 src/components/email-block/logic/store.js 파일로 이동하여 다음 코드 세그먼트를 추가합니다.
    import create from "zustand";
    import { devtools } from "zustand/middleware";
    import { initContentModel, initLoadingModel } from "./data-models";
    
    const [useStore] = create(
      devtools((set) => ({
        ...initContentModel(set),
        ...initLoadingModel(set)
      })),
      "smart-blocks-store"
    );
    
    export { useStore };
    
    우리는 디버깅을 돕기 위해 개발 도구를 사용하고 있다.Zustand 개발 도구에 대한 자세한 내용은 Zustand's documentation on dev tools:

    축하합니다!현재 스토어가 만들어졌습니다.🎉

    구성 요소에 스토리지 연결


    상점을 구성 요소에 연결하려면 연결고리만 사용하면 된다.src/components/email-block/EmailBlock.js를 되돌려주고 src/components/email-block/logic/store.js 파일에서useStore를 가져옵니다.
    우리는 useStore를 사용하여 내용, 불러오는 상태와 처리 상태를 얻을 것이다.
    import React from "react";
    import { Box, Text, Heading } from "grommet";
    import { TextField } from "@material-ui/core";
    import theme from "../../theme";
    import Button from "./Button";
    import LoadingBlock from "./LoadingBlock";
    import { useStore } from "./logic/store";
    
    const { colors } = theme;
    
    const WrapperBox = ({ children }) => (
      <Box
        elevation={"large"}
        width={"500px"}
        round="8px"
        background={colors.white}
        pad={"large"}
        gap={"medium"}
      >
        {children}
      </Box>
    );
    
    const EmailBlock = () => {
      const [isLoading, isProcessing] = useStore((state) => [
        state.loading,
        state.processing
      ]);
    
      const [content, currentButtonText] = useStore((state) => [
        state.content,
        state.currentButtonText
      ]);
    
      return (
        <>
          {isLoading && (
            <WrapperBox>
              <LoadingBlock />
            </WrapperBox>
          )}
          {!isLoading && (
            <WrapperBox>
              <Heading level={1} color={colors.black}>
                {content.title}
              </Heading>
              <Text size={"medium"}>{content.subTitle}</Text>
              <TextField {...content.input} />
              <Button
                type="submit"
                onClick={(e) => {
                  e.preventDefault();
                }}
                disabled={isProcessing}
                background={colors.primary}
                color={colors.white}
                style={{
                  paddingTop: "16px",
                  paddingBottom: "16px"
                }}
              >
                {currentButtonText}
              </Button>
            </WrapperBox>
          )}
        </>
      );
    };
    
    export default EmailBlock;
    
    

    연결 테스트


    이 때 텍스트가 fallback.js 파일에서 성공적으로 추출된 것을 보아야 합니다.또한 로드 초기 상태를true로 설정하고 구성 요소 UI에 실제로 뼈대 로드 프로그램이 표시되어 있는지 확인하여 연결을 테스트할 수 있습니다.

    단추에 할당 만들기


    현재 UI는 Zustand 스토어에 완전히 연결되어 있으며 버튼 스케줄링을 관리할 수 있습니다.경고로, 우리의 전문적인 선호도는 flows.js 파일에서 사용자가 촉발하는 이벤트를 조직하는 것이다.이렇게 하면 버튼 클릭과 같이 사용자 이벤트 후에 버튼 상태를 전환할 수 있습니다.

    네트워크 지연을 시뮬레이션하기 위해 wait 함수를 만듭니다.flows.js 파일에 다음 코드 세그먼트를 추가합니다.
    const wait = async (time) =>
      new Promise((resolve) => setTimeout(() => resolve(true), time));
    
    
    같은 파일에서 빈 함수 useDispatchEmailFlow 를 만듭니다. 이 함수는 비동기 스케줄링 함수를 되돌려줍니다.
    const useDispatchEmailFlow = () => {
    
      const dispatch = async () => {};
    
      return dispatch;
    }
    
    
    완료되면 다음 코드 업데이트useDispatchEmailFlow 함수를 사용합니다.
    import { useStore } from "./store";
    
    const wait = async (time) =>
      new Promise((resolve) => setTimeout(() => resolve(true), time));
    
    const useDispatchEmailFlow = () => {
      const [
        setProcessing,
        clearProcessing,
        setButtonText,
        buttonStates
      ] = useStore((store) => [
        store.setProcessing,
        store.clearProcessing,
        store.setButtonText,
        store.content?.button?.states
      ]);
    
      const dispatch = async () => {
        setProcessing();
        setButtonText(buttonStates?.processing);
        await wait(2000);
        setButtonText(buttonStates?.success);
        await wait(1000);
        setButtonText(buttonStates?.initial);
        clearProcessing();
      };
      return dispatch;
    };
    
    export { useDispatchEmailFlow };
    
    
    보시다시피useuseDispatchEmailFlow에서는Zustand store를 사용하여 기능setProcessing,clearProcessing,setButtonText와 단추의 내용을 얻습니다.디스패치 함수에서, 우리는 wait 함수를 사용하여 네트워크 호출을 시뮬레이션합니다.
    현재, 단추를 눌렀을 때, 단추가 비활성화되고, 상태를 바꾸고, 리셋되는 것을 볼 수 있습니다.멋있죠?!

    결론


    이렇게!이 시리즈의 이 부분에서 데이터 모델을 설정하고 저장을 만들고 React 구성 요소에 연결하는 방법을 배웠습니다.

    Part 3 of this tutorial로 가면 웹 응용 프로그램에 백엔드 논리와 마이크로 서비스 데이터 자원을 만들 것입니다.우리의 목표는 20분 이내에 모든 것을 완성하고 배치하는 것이다.
    이 프로그램이 완성된 것을 여기Code Sandbox에서 찾을 수 있습니다.

    좋은 웹페이지 즐겨찾기