3일차에 했던 유저리스트에 눌러서 액티브가 true인 유저 수를 카운트해서 나타내보기.
userMemo() => 리액트에서 컴포넌트 성능을 최적화 하는데 사용되는 훅
memo => memoization의 약자 메모리에 넣기
동일한 계산을 반복해야 할 때, 이전의 값을 메모리에 저장함으로써
반복수행을 제거하여 프로그램 실행 속도를 빠르게 해주는 기술
함수형 컴포넌트가 랜더링 => 컴포넌트 함수 호출 => 모든 내부 변수 초기화
useMemo 랜더링 => 함수 호출 => memoize 된 함수를 재사용
const countActiveUser = (users) => {
// user.active 가 true 인 사용자를 카운트해서 리턴
return (users.filter(user => user.active).length);
}
const count = useMemo(() => countActiveUser(users), [users])
필터를 이용해서 true인 수의 길이를 리턴해서 바로 받아주고
<div>완료 사용자 수 : {count}</div> 를 추가해서 나타내주면
결과
누르면 완료 사용자 수가 늘어나는 걸 볼 수 있음.
css파일 안만들고 hover 해보기
1. useState로 상태정의
const [isHovered, setIsHovered] = useState(false);
2. 원하는 css 작성
위에서 정의했던걸 이용해서 호버됐을때, 안됐을때 ture , false로 backgrounColor를 설정
const buttonStyle = {
marginBottom: "40px",
width: "78%",
backgroundColor: isHovered ? "blue" : "#007bff",
};
3. onMouseEnter , onMouseLeave 이벤트를 이용해서 true, false 일때 스타일이 작동하도록 설정
<Button style={buttonStyle} onClick={onCreate}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>Create</Button>{' '}
배웠던거 응용해서 TodoList 만들기
조건
1. 인풋 2개로 내용을 받고 추가 / 삭제 버튼 있어야함
2. 리스트 안의 내용을 눌러 취소선을 그을 수 있어야함
3. 그냥 만들기만하지말고 CSS로 나름 꾸미기
import React from 'react';
import TodoCreate from './TodoCreate';
import Todo from './Todo';
import { useState } from 'react';
import { useRef } from 'react';
import './Todo.css';
const TodoList = () => {
const nextId = useRef(0);
const [todos, setTodos] = useState([]);
const [todoname , setTodoname] = useState();
const onChange = (e) => {
setTodoname(e.target.value);
}
const onAdd = () => {
const todo = {
id:nextId.current,
todoname : todoname,
};
setTodos( todos.concat(todo));
setTodoname('');
nextId.current += 1;
}
const onRemove = (id) => {
setTodos(todos.filter(todo => todo.id !== id))
}
const onToggle = (id) => {
setTodos(todos.map( todo => todo.id === id ? { ...todo, active : !todo.active} : todo))
}
return (
<div className='todolist'>
<h1 className="todo-title">My Todo List</h1>
<TodoCreate todoname={todoname} onChange={onChange} onAdd={onAdd}/>
<ul className='todo-list'>
{
todos.map( t => (
<li className='todo-item'>
<Todo todo = {t} key = {t.id} onRemove = {onRemove} onToggle={onToggle} />
</li>
))
}
</ul>
</div>
);
};
export default TodoList;
import React from 'react';
import './Todo.css';
const Todo = ( {todo, onRemove, onToggle}) => {
return (
<div className='todo'>
<h3>
<span
style={{
color: todo.active ? "red" : "#ff6f61",
textDecoration: todo.active ? "line-through" : "none",
cursor:"pointer"
}}
onClick={() => onToggle(todo.id)}>{todo.todoname}</span>
<button onClick={() => onRemove(todo.id)}>X</button>
</h3>
</div>
);
};
export default Todo;
import React from 'react';
import './Todo.css';
const TodoCreate = ({todoname, onChange, onAdd}) => {
return (
<div className='todocreate'>
<div className='todo-input'>
<input type="text" name='todoname' placeholder='Todo' onChange={onChange} value={todoname}/>
<button onClick={onAdd}>add</button>
</div>
</div>
);
};
export default TodoCreate;
.todo-input input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
body{
background-color: #f9f5f0;
}
.todo-input {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.todo-input input:focus {
border-color: #ff9aa2;
outline: none;
}
.todocreate{
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 40px;
}
.todo-input button:hover {
background-color: #f5a4a4;
}
.todocreate button{
padding: 10px 20px;
background-color: #f6c1c1;
border: none;
border-radius: 4px;
color: #fff;
font-size: 16px;
cursor: pointer;
}
.todo-list {
list-style-type: none;
padding: 0;
}
.todo-item {
width: 60%;
margin: 0 auto;
padding: 15px;
margin-bottom: 10px;
background-color: #fef5f5;
border: 1px solid #f1c6c6;
border-radius: 8px;
font-size: 18px;
transition: background-color 0.3s ease, transform 0.2s ease;
}
.todo-title {
color: #b67ccf;
margin-bottom: 20px;
}
.todo-item:hover {
background-color: #fce4e4;
transform: scale(1.02);
}
.todo-item button {
padding: 8px 12px;
background-color: #ff9aa2;
border: none;
border-radius: 4px;
color: #fff;
font-size: 14px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
outline: none;
display: inline-block;
text-align: center;
}
.todo-item button:hover {
background-color: #ff6f6f;
transform: scale(1.05);
}
.todo{
width: 100%;
}
.todo h3{
display: flex;
justify-content: space-between;
}
.todo h3 span{
margin-left: 60px;
}
결과
axios ( 외장 라이브러리 별도 설치 필요 )
=> js ajax ( js 내장 라이브러리 )
url : 요청 주소
method : get(요청), post(삽입), put, patch(수정) , delete(삭제)
response : 응답 객체
request : 요청 객체
axios.get( url [, config] )
axios.post( url [, config] [, data] )
axios.put ( url [, config] [, data] )
axios.delete ( url [, config] )
useEffect : 컴포넌트가 랜더링 될 때, 혹은 업데이트 될 때 실행되는 hook
useEffect((function),deps)
function : 실행시킬 함수
deps : 배열형태
[] 빈배열 : 마운트 될 때 만 실행
x : 매번 랜더링 될 때 마다 실행
[name] : 업데이트 될 때 마다 실행
https://jsonplaceholder.typicode.com/users 에서 데이터를 가져와보기
import React from 'react';
import { useEffect } from 'react';
import { useState } from 'react';
import axios from 'axios';
const User = () => {
const [ users, setUsers ] = useState([]);
// 다운로드가 잘되었는지 확인용 / 에러 확인용
const [ loading, setLoading ] = useState(false);
const [ error, setError ] = useState(null);
const fetchUsers = async () => {
try{
// 요청이 시작되면 loding의 상태를 true로 변경
setLoading(true);
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
console.log(response);
setUsers(response.data); // data는 response.data 안에 담겨있음.
} catch(e){
setError(e);
}
setLoading(false);
}
// useEffect(() => {
// fetchUsers();
// },[]);
if(loading) return <div>로딩중...</div>;
if(error) return <div>에러가 발생했습니다.</div>
// if(!users) return <div>User null!!!</div>
return (
<div className='user'>
<div>User.jsx 영역</div>
<ul>
{
users.map(user => (
<li key={user.id}>{user.username} ({user.name}) : {user.email}</li>
))
}
</ul>
{/* button을 추가하여 클릭시 user 데이터가 뜰 수 있도록 설정 */}
<button onClick={fetchUsers}>Create</button>
</div>
);
};
export default User;
버튼을 누르면 데이터를 가져와서 생성하는 것을 볼 수 있음.
'React 수업 정리' 카테고리의 다른 글
Board 만들어보기 (0) | 2024.09.19 |
---|---|
React 5일차 (0) | 2024.09.10 |
React 3일차 (0) | 2024.09.06 |
React 2일차 (1) | 2024.09.05 |
React 1일차 (2) | 2024.09.04 |