230518 - React(useMemo), firebase(구글로그인)

백승연·2023년 5월 18일
1

🚩 React

배열 추가, 삭제, 속성 수정(응용2)

📝 설명

  • 어제 마지막으로 한 내용에서 변수의 이름을 통일하지 않고 다시 코딩


✒️ 사용법

입력

App.js

import { useRef, useState } from "react";
import CreateUser from "./CreateUser";
import "./styles.css";
import UserList from "./UserList";

export default function App() {
  const initialUsers = [
    {
      id: 1,
      username: "Bret",
      email: "Sincere@april.biz",
      active: true
    },
    {
      id: 2,
      username: "Antonette",
      email: "Shanna@melissa.tv",
      active: false
    },
    {
      id: 3,
      username: "Samantha",
      email: "Nathan@yesenia.net",
      active: false
    },
    {
      id: 4,
      username: "Karianne",
      email: "Julianne.OConner@kory.org",
      active: false
    }
  ];

  const [users, setUsers] = useState(initialUsers); //배열전체
  const [inputs, setInputs] = useState({ username: "", email: "" }); // input(2개) 안의 내용(value)을 임시저장할 배열 (username, email은 기존 배열의 이름과 같게)

  // state안에 있는 상태
  const usernameState = inputs.username;
  const emailState = inputs.email;

  const changeText = (event) => {
    const nameInput = event.target.name; // username, email 중 하나. (어떤 input 인지)
    const valueInput = event.target.value; // input에 입력 된 값

    setInputs({ ...inputs, [nameInput]: valueInput });
    console.log(inputs);
  };

  // create를 누를 때 마다 id값이 1씩 증가하도록 하는 변수 설정
  const nextId = useRef(5); // 배열 아이템에 들어 갈 id
  const focusIn = useRef(); // 특정한 DOM(엘리먼트) 선택을 위한 설정

  const onCreate = (event) => {
    console.log("onCreate 함수 실행");

    const item = {
      id: nextId.current,
      username: usernameState,
      email: emailState
    };

    setUsers([...users, item]); // 배열에 아이템을 넣는 함수 실행
    setInputs({ username: "", email: "" }); // input 초기화

    nextId.current += 1;
    focusIn.current.focus();
  };

  // 삭제 함수 정의
  const remove = (id) => {
    // console.log("아이디는? : ", id);
    setUsers(users.filter((item) => item.id !== id)); // 내가 고른 id값을 빼고 다시 배열을 만듦
  };

  // username 색을 바꿔주는 토글함수
  const toggleColor = (id) => {
    setUsers(
      users.map(
        (item) =>
          // item은 {} 한 개를 의미
          // item.active = active의 key값을 의미
          item.id === id ? { ...item, active: !item.active } : item // 명령어 한 줄 (중괄호 필요x)
      )
    );
  };

  return (
    <div>
      <CreateUser
        func={changeText}
        func2={onCreate}
        uu={usernameState}
        ee={emailState}
        focusRef={focusIn}
      />
      <br />
      <br />
      <UserList users={users} onRemove={remove} onToggle={toggleColor} />
    </div>
  );
}



CreateUser.jsx

import React from "react";

export default function CreateUser(props) {
  return (
    <>
      <input
        type="text"
        name="username"
        placeholder="유저네임"
        onChange={props.func}
        value={props.uu}
        ref={props.focusRef}
      />
      <input
        type="email"
        name="email"
        placeholder="이메일"
        onChange={props.func}
        value={props.ee}
      />
      <button onClick={props.func2}>등록</button>
    </>
  );
}



UserList.jsx

import React from "react";

//컴포넌트 추가 정의
function User(props) {
  return (
    <div className={props.item.id}>
      <b
        style={{
          color: props.item.active ? "orange" : "gray",
          cursor: "pointer",
          marginRight: 5
        }}
        onClick={() => props.tt(props.item.id)}
      >
        {props.item.username}
      </b>{" "}
      <span>({props.item.email})</span>
      <button
        onClick={() => {
          props.rr(props.item.id); // 몇 번째 값을 선택했는지 아이디값을 받아옴
        }}
      >
        삭제
      </button>
    </div>
  );
}

// onRemove는 key값이 넘어감
export default function UserList({ users, onRemove, onToggle }) {
  return (
    <>
      {users.map((item) => (
        // 이 rr이 위 User 함수의 rr로 넘어감
        <User item={item} key={item.id} rr={onRemove} tt={onToggle} />
      ))}
    </>
  );
}

출력

  • 이미지로 대체


🔗 참고 링크 & 도움이 되는 링크






배열 추가, 삭제, 속성 수정(리팩토링)

📝 설명

  • 위에서 작성한 코드 리팩토링


✒️ 사용법

입력

App.js

import { useRef, useState } from "react";
import CreateUser from "./CreateUser";
import "./styles.css";
import UserList from "./UserList";

export default function App() {
  const initialUsers = [
    {
      id: 1,
      username: "Bret",
      email: "Sincere@april.biz",
      active: true
    },
    {
      id: 2,
      username: "Antonette",
      email: "Shanna@melissa.tv",
      active: false
    },
    {
      id: 3,
      username: "Samantha",
      email: "Nathan@yesenia.net",
      active: false
    },
    {
      id: 4,
      username: "Karianne",
      email: "Julianne.OConner@kory.org",
      active: false
    }
  ];

  const [users, setUsers] = useState(initialUsers); //배열전체
  const [inputs, setInputs] = useState({ username: "", email: "" }); // input(2개) 안의 내용(value)을 임시저장할 배열 (username, email은 기존 배열의 이름과 같게)

  // state안에 있는 상태. 위 아래 둘 다 같은 표현
  // const username = inputs.username;
  // const email = inputs.email;
  const { username, email } = inputs;

  const changeText = (event) => {
    // const name = event.target.name; // username, email 중 하나. (어떤 input 인지)
    // const value = event.target.value; // input에 입력 된 값
    const { name, value } = event.target;

    setInputs({ ...inputs, [name]: value });
    // console.log(inputs);
  };

  // create를 누를 때 마다 id값이 1씩 증가하도록 하는 변수 설정
  const nextId = useRef(5); // 배열 아이템에 들어 갈 id
  const focusIn = useRef(); // 특정한 DOM(엘리먼트) 선택을 위한 설정

  const onCreate = () => {
    console.log("onCreate 함수 실행");

    const item = {
      id: nextId.current, // key: value
      username,
      email
    };

    setUsers([...users, item]); // 배열에 아이템을 넣는 함수 실행
    setInputs({ username: "", email: "" }); // input 초기화

    nextId.current += 1;
    focusIn.current.focus();
  };

  // 삭제 함수 정의
  const remove = (id) => {
    // console.log("아이디는? : ", id);
    setUsers(users.filter((item) => item.id !== id)); // 내가 고른 id값을 빼고 다시 배열을 만듦
  };

  // username 색을 바꿔주는 토글함수
  const toggleColor = (id) => {
    setUsers(
      users.map(
        (item) =>
          // item은 {} 한 개를 의미
          // item.active = active의 key값을 의미
          item.id === id ? { ...item, active: !item.active } : item // 명령어 한 줄 (중괄호 필요x)
      )
    );
  };

  return (
    <div>
      <CreateUser
        changeText={changeText}
        onCreate={onCreate}
        username={username}
        email={email}
        focusRef={focusIn}
      />
      <br />
      <br />
      <UserList users={users} remove={remove} toggleColor={toggleColor} />
    </div>
  );
}



CreateUser.jsx

import React from "react";

export default function CreateUser({
  changeText,
  onCreate,
  username,
  email,
  focusRef
}) {
  return (
    <>
      <input
        type="text"
        name="username"
        placeholder="유저네임"
        onChange={changeText}
        value={username}
        ref={focusRef}
      />
      <input
        type="email"
        name="email"
        placeholder="이메일"
        onChange={changeText}
        value={email}
      />
      <button onClick={onCreate}>등록</button>
    </>
  );
}



UserList.jsx

import React from "react";

//컴포넌트 추가 정의
function User({ item, toggleColor, remove }) {
  // "item."을 없애기 위해 다시 지정
  const { id, active, username, email } = item;
  return (
    <div className={id}>
      <b
        style={{
          color: active ? "orange" : "gray",
          cursor: "pointer",
          marginRight: 5
        }}
        onClick={() => toggleColor(id)}
      >
        {username}
      </b>{" "}
      <span>({email})</span>
      <button
        onClick={() => {
          remove(id); // 몇 번째 값을 선택했는지 아이디값을 받아옴
        }}
      >
        삭제
      </button>
    </div>
  );
}

// onRemove는 key값이 넘어감
export default function UserList({ users, remove, toggleColor }) {
  return (
    <>
      {users.map((item) => (
        // 이 rr이 위 User 함수의 rr로 넘어감
        <User
          item={item}
          key={item.id}
          remove={remove}
          toggleColor={toggleColor}
        />
      ))}
    </>
  );
}

출력

  • 이미지로 대체

🔗 참고 링크 & 도움이 되는 링크






useMemo

  • 위에서 작성한 코드 리팩토링한 내용에 useMemo()를 사용하여 active가 있는 사용자 수 계산.

📝 설명

  • React Hooks 중 하나
  • 이전에 연산된 값을 재사용, memorization
  • 성능을 최적화 할 때 사용, 필요할 때만 연산
  • const 결과값 = useMemo(함수, dependencies(=변화를 감지 할 요소))


✒️ 사용법

입력

App.js

import { useRef, useState, useMemo } from "react";
import CreateUser from "./CreateUser";
import "./styles.css";
import UserList from "./UserList";

// active된 아이템 숫자를 세 주는 함수
// array를 인자로 받아옴
function countActiveUsers(users) {
  return users.filter((item) => item.active).length;
}
// 필요 없을때도 너무 자주 실행됨 (데이터 낭비, 성능 하락) -> useMemo를 사용

export default function App() {
  const initialUsers = [
    {
      id: 1,
      username: "Bret",
      email: "Sincere@april.biz",
      active: true
    },
    {
      id: 2,
      username: "Antonette",
      email: "Shanna@melissa.tv",
      active: false
    },
    {
      id: 3,
      username: "Samantha",
      email: "Nathan@yesenia.net",
      active: false
    },
    {
      id: 4,
      username: "Karianne",
      email: "Julianne.OConner@kory.org",
      active: false
    }
  ];

  const [users, setUsers] = useState(initialUsers); //배열전체
  const [inputs, setInputs] = useState({ username: "", email: "" }); // input(2개) 안의 내용(value)을 임시저장할 배열 (username, email은 기존 배열의 이름과 같게)

  // state안에 있는 상태. 위 아래 둘 다 같은 표현
  // const username = inputs.username;
  // const email = inputs.email;
  const { username, email } = inputs;

  const changeText = (event) => {
    // const name = event.target.name; // username, email 중 하나. (어떤 input 인지)
    // const value = event.target.value; // input에 입력 된 값
    const { name, value } = event.target;

    setInputs({ ...inputs, [name]: value });
    // console.log(inputs);
  };

  // create를 누를 때 마다 id값이 1씩 증가하도록 하는 변수 설정
  const nextId = useRef(5); // 배열 아이템에 들어 갈 id
  const focusIn = useRef(); // 특정한 DOM(엘리먼트) 선택을 위한 설정

  const onCreate = () => {
    console.log("onCreate 함수 실행");

    const item = {
      id: nextId.current, // key: value
      username,
      email
    };

    setUsers([...users, item]); // 배열에 아이템을 넣는 함수 실행
    setInputs({ username: "", email: "" }); // input 초기화

    nextId.current += 1;
    focusIn.current.focus();
  };

  // 삭제 함수 정의
  const remove = (id) => {
    // console.log("아이디는? : ", id);
    setUsers(users.filter((item) => item.id !== id)); // 내가 고른 id값을 빼고 다시 배열을 만듦
  };

  // username 색을 바꿔주는 토글함수
  const toggleColor = (id) => {
    setUsers(
      users.map(
        (item) =>
          // item은 {} 한 개를 의미
          // item.active = active의 key값을 의미
          item.id === id ? { ...item, active: !item.active } : item // 명령어 한 줄 (중괄호 필요x)
      )
    );
  };

  // active 적용된 이름 숫자 세주는 함수 실행
  // useMemo(함수, 변화요소)
  const count = useMemo(() => countActiveUsers(users), [users]);

  return (
    <div>
      <CreateUser
        changeText={changeText}
        onCreate={onCreate}
        username={username}
        email={email}
        focusRef={focusIn}
      />
      <br />
      <br />
      <UserList users={users} remove={remove} toggleColor={toggleColor} />
      <hr />

      <div>Active 사용자 수 : {count}</div>

      <dl>
        <dt>useMemo</dt>
        <dd>React Hooks 중 하나</dd>
        <dd>이전에 연산된 값을 재사용, memorization</dd>
        <dd>성능을 최적화 할 때 사용, 필요할 때만 연산</dd>
        <dd>
          const 결과값 = useMemo(함수, dependencies(=변화를 감지 할 요소))
        </dd>
      </dl>
    </div>
  );
}



CreateUser.jsx

import React from "react";

export default function CreateUser({
  changeText,
  onCreate,
  username,
  email,
  focusRef
}) {
  return (
    <>
      <input
        type="text"
        name="username"
        placeholder="유저네임"
        onChange={changeText}
        value={username}
        ref={focusRef}
      />
      <input
        type="email"
        name="email"
        placeholder="이메일"
        onChange={changeText}
        value={email}
      />
      <button onClick={onCreate}>등록</button>
    </>
  );
}



UserList.jsx

import React from "react";

//컴포넌트 추가 정의
function User({ item, toggleColor, remove }) {
  // "item."을 없애기 위해 다시 지정
  const { id, active, username, email } = item;
  return (
    <div className={id}>
      <b
        style={{
          color: active ? "orange" : "gray",
          cursor: "pointer",
          marginRight: 5
        }}
        onClick={() => toggleColor(id)}
      >
        {username}
      </b>{" "}
      <span>({email})</span>
      <button
        onClick={() => {
          remove(id); // 몇 번째 값을 선택했는지 아이디값을 받아옴
        }}
      >
        삭제
      </button>
    </div>
  );
}

// onRemove는 key값이 넘어감
export default function UserList({ users, remove, toggleColor }) {
  return (
    <>
      {users.map((item) => (
        // 이 rr이 위 User 함수의 rr로 넘어감
        <User
          item={item}
          key={item.id}
          remove={remove}
          toggleColor={toggleColor}
        />
      ))}
    </>
  );
}

출력

  • 이미지로 대체

🔗 참고 링크 & 도움이 되는 링크






🚩 Firebase

firebase란?

📝 설명

  • google의 모바일 애플리케이션 개발 플랫폼
  • 앱을 쉽게 개발할 수 있는 개발 툴


firebase로 google login 사용하기

📝 설명

  • javascript를 사용하여 구글 로그인을 사용할 수 있게 함


✒️ 사용법

입력

html

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>
      <a href="" id="googleLoginBtn"
        ><img src="google.png" alt="구글 아이디로 로그인"
      /></a>
    </div>
  </body>

  <script type="module">
    // Import the functions you need from the SDKs you need
    import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
    import {
      getAuth,
      signInWithPopup,
      GoogleAuthProvider,
    } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-auth.js";
    // signInWithPopup : 팝업 창을 사용하여 로그인 진행

    const firebaseConfig = {
      apiKey: "AIzaSyA5fQIlYMLD0fppAFs5fyvE3s4lcvUmyfI",
      authDomain: "test-d6f37.firebaseapp.com",
      projectId: "test-d6f37",
      storageBucket: "test-d6f37.appspot.com",
      messagingSenderId: "1008714124009",
      appId: "1:1008714124009:web:6a1bfdb23867b04cc27e78",
    };

    // Initialize Firebase
    const app = initializeApp(firebaseConfig);
    console.log("app 작동? : ", app);

    const provider = new GoogleAuthProvider(); // google auth 생성자 (객체 생성)
    const auth = getAuth();

    document
      .querySelector("#googleLoginBtn")
      .addEventListener("click", (event) => {
        event.preventDefault();

        signInWithPopup(auth, provider)
          .then((result) => {
            // This gives you a Google Access Token. You can use it to access the Google API.
            const credential = GoogleAuthProvider.credentialFromResult(result);
            const token = credential.accessToken;
            // The signed-in user info.
            const user = result.user;
            window.location.href="https://www.naver.com"; // 로그인 성공하면 naver로 넘어감
          })
          .catch((error) => {
            // Handle Errors here.
            const errorCode = error.code;
            const errorMessage = error.message;
            // The email of the user's account used.
            const email = error.customData.email;
            // The AuthCredential type that was used.
            const credential = GoogleAuthProvider.credentialFromError(error);
            // ...
          });
      });
  </script>
</html>

출력

  • 이미지로 대체

로그인 창

로그인 되면 네이버로 페이지 이동


🔗 참고 링크 & 도움이 되는 링크






profile
공부하는 벨로그

0개의 댓글