Zustand 설치

yarn add zustand

우리는!

git clone <https://github.com/pepperdad/zustand-practice>

스토어 추가

// src/store/MemoList.js
import { create } from "zustand";

export const useMemoStore = create((set) => ({
  memoList: [],
  addMemo: (val) =>
    set((prev) => ({
      memoList: [
        ...prev.memoList,
        { content: val, id: new Date().getMilliseconds() + val },
      ],
    })),
  removeMemo: (id) =>
    set((prev) => ({ memoList: prev.memoList.filter((e) => e.id !== id) })),
}));
// MemoInput.jsx
import { useState } from "react";
import styled from "styled-components";
import { useMemoStore } from "./../store/MemoList";

const MemoInput = () => {
  const { addMemo } = useMemoStore();
  const [value, setValue] = useState("");

  return (
    <AddMemoForm
      onSubmit={(e) => {
        e.preventDefault();
        addMemo(value);

        setValue("");
      }}
    >
      <div>
        <input
          type="text"
          onChange={(e) =>
            setValue((prev) => {
              if (prev !== e.target.value) {
                return e.target.value;
              }
            })
          }
          value={value}
        />
        <button type="submit">저장</button>
      </div>
    </AddMemoForm>
  );
};

export default MemoInput;

const AddMemoForm = styled.form`
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  margin: 16px;
  > div {
    position: relative;
    width: 400px;
    height: 200px;
  }
  input {
    width: 100%;
    height: 100%;
    text-align: center;
  }
  button {
    position: absolute;
    bottom: 0;
    right: 0;
  }
`;

// MemoElem.jsx
import styled from "styled-components";
import { useMemoStore } from "../store/MemoList";

const MemoElem = (props) => {
  const { children, id } = props;
  const { removeMemo } = useMemoStore();

  return (
    <MemoWrapper>
      <div>{children}</div>
      <RemoveButton onClick={() => removeMemo(id)}>삭제</RemoveButton>
    </MemoWrapper>
  );
};

export default MemoElem;

const MemoWrapper = styled.div`
  position: relative;
  width: 200px;
  height: 200px;
  padding: 16px;
  border: 1px solid orange;
  background-color: lightyellow;
  border-radius: 8px;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 16px;
  z-index: 999;
`;

const RemoveButton = styled.button`
  padding: 4px 7px;
  background-color: transparent;
  border: 1px solid #ccc;
  color: #999;
  position: absolute;
  top: 4px;
  right: 4px;
`;

// App.jsx
import MemoBoard from "./components/MemoBoard";
import MemoElem from "./components/MemoElem";
import MemoInput from "./components/MemoInput";
import { useMemoStore } from "./store/MemoList";

const App = () => {
  const { memoList } = useMemoStore();
  return (
    <>
      <MemoBoard>
        {memoList.length ? (
          memoList.map((e) => {
            return (
              <MemoElem key={e.id} id={e.id}>
                {e.content}
              </MemoElem>
            );
          })
        ) : (
          <span>메모를 입력해주세요</span>
        )}
      </MemoBoard>
      <MemoInput />
    </>
  );
};

export default App;

Snippet

Untitled

다음과 같은 Snippet을 추가하면,

// zst
import { create } from 'zustand'

export const useYourStore = create((set)=>({
  yourState : 'VALUE',
  yourAction : (val) => set( (state) => ({ yourState : state.yourState }) )
}))

// zus
import { create } from 'zustand'

export const useYourStore = create((set)=>({
  yourState : 'VALUE',
  yourAction : (val) => set( (state) => ({ yourState : state.yourState }) )
}))

이런 형식으로 사용할 수 있다~!