리액트

[React] DB없이 프론트에서 useState로 데이터를 관리하기 (localstorage ❌)

joheamin 2025. 3. 18. 01:18

일반적으로 프론트에서 데이터를 입력받아서 저장하게 될 경우 백엔드를 통하여 DB안에 저장하게 된다.

 

하지만 백엔드와 DB없이 프론트 안에서만 데이터를 저장하고 관리하는 것도 번거롭지만 가능하다.

 

오늘은 프론트엔드만 사용하여 데이터들을 관리하고 저장하는것을 

회원과 게시물을 예시로 들어서 만들어 보겠다.

 

🔴 생성할 파일

  • Join.jsx : 회원의 정보를 입력 받아 저장
  • Login.jsx : 아이디와 비밀번호를 입력받아 일치하는 계정으로 로그인하고 로그인 유저의 정보 저장

 

🤔 데이터는 어디에서 관리하는 것이 좋을까?

일반적으로 프론트에서 데이터를 임시 저장할 때는 localStorage 나 sessionStorage를 사용한다.

 

그러나 회원들의 정보나 대량의 데이터들을 모두 저장하기에는 사실 적합한 방법은 아니다.

 

따라서 오늘은 useState를 통하여 최상단 컴포넌트에서 관리를 하여 하위컴포넌트에서 모두 데이터를 참조할 수 있도록 

설계를 해볼 생각이다.

 

🤔 왜 최상단 컴포넌트에서 관리하는 것이 좋을까?

컴포넌트간에 데이터 전달을 할때 상위에서 하위로의 전달은 가능하나 

하위에서 상위로는 전달이 불가능하다.

 

여러 컴포넌트에서 어떠한 데이터를 원할때 그 데이터를 내려주는 공통된 상위의 컴포넌트가 있어야한다.

 

따라서 최상위 컴포넌트에 데이터를 저장 하므로써 다양한 컴포넌트에서 데이터를 똑같이 내려받을 수 있게된다.

 

 

🔷 기본적인 UI 생성

◾ Join.jsx
export default function Join() {
  return (
    <>
      <div>
        <h1>회원가입</h1>
        <input type="text" placeholder="아이디" />
        <br />
        <input type="text" placeholder="비밀번호" />
        <br />
        <input type="text" placeholder="이름" />
        <br />
      </div>
    </>
  );
}​

◾ Login.jsx

export default function Login() {
  return (
    <>
      <div>
        <h1>로그인</h1>
        <input type="text" placeholder="아이디" />
        <br />
        <input type="text" placeholder="비밀번호" />
      </div>
    </>
  );
}

◾ App.js

function App() {
  return (
    <>
      <Join />
      <Login />
      <Board />
    </>
  );
}

 



 

 

🔹 회원 가입

1️⃣ App.js 최상위 컴포넌트에서 회원들의 정보를 담아 관리할 useState 생성 후
      회원을 저장하는 함수를 정의 
  // 회원 목록을 저장하는 상태
  const [members, setMembers] = useState([]);
  // 아이디값으로 넣을 변수
  const idRef = useRef(1);
  
    // 회원가입 시 members 배열에 사용자 추가하는 함수
  const joinMember = (user) => {
    const newUser = {
      id: idRef.current,
      email: user.email,
      password: user.password,
      name: user.name,
    };
	
    //기존 members의 데이터를 그대로 가져오며 새로운 user에 데이터를 가장 앞쪽에 저장한다.
    setMembers([newUser, ...members]);
    //아이디는 1 증가
    idRef.current += 1;
  };


2️⃣ Join 컴포넌트에 콜백 함수로 전달

return(
	<Join joinMember = {joinMember} /> 
);


3️⃣ Join에서 데이터를 입력 받아 객체화 하여 전달받은 콜백 함수 호출

  
  //joinMember 콜백함수로 받아옴
  export default function Join({joinMember}) {
  
  //입력값 상태변수
  const [email, setEmail] = useState("");
  const [pw, setPw] = useState("");
  const [name, setName] = useState("");
  
  //회원가입 버튼 클릭
    const onClickBtn = () => {
      //데이터를 객체로 저장하여 전달받은 콜백함수에 인자로 넣어 호출
      const newUser = { email, pw, name };
      joinMember(newUser);
  };
  
  return(
  	<button onClick={()=> onClickBtn()}>회원가입</button> 
  );
  }

 

 

🔹 로그인

1️⃣ 로그인 된 유저와 로그인 여부를 담을 상태변수 생성
function App() {

  const [members,setMembers] = useState([]);      //회원들 
  const [isLogin, setIsLogin] = useState(false);  //로그인 여부
  const [loginUser, setLoginUser] = useState([]); //로그인 유저
  	
    return(
    	<Login 
        	setIsLogin = {setIsLogin} 
            setLoginUser = {setLoginUser}
            members = {members} />
    );
  }​

 

👉 로그인 여부와 로그인 유저 정보를 업데이트하기 위해 set 함수와 로그인을 위해 조회할 members를 콜백함수로 전달

2️⃣ members에서 일치하는 회원 데이터를 찾아 로그인
export default function Login() {


//로그인 버튼 클릭 시
const onClickConfirmButton = () => {
    //로그인 버튼 클릭 시 정보와 일치하는 회원을 찾아 user에 저장
    const user = members.find(
      (member) => member.email === email && member.password === pw
    );

	//만약 일치하는 데이터가 있을 경우
    if (user) {
      setIsLogin(true);  //로그인 여부 활성화
      setLoginUser(user); //로그인 유저 저장
    } else {
      alert("등록되지 않은 회원이거나 잘못 입력하셨습니다.");
    }
 }
  };​
👉 find 를 통해 회원 데이터에서 입력한 로그인 값과 일치하는 것이 존재한다면
      해당하는 회원의 정보를 저장하고 로그인 여부 활성화