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}
/>
))}
</>
);
}
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}
/>
))}
</>
);
}
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>
로그인 창
로그인 되면 네이버로 페이지 이동