[TIL] React 공부일기 #5

Hyeonu_J·2021년 8월 16일
0
post-thumbnail

웹 애플리케이션 만들기


다음장 최적화 챕터까지 포함해서 책에 써져있는대로 코드를 짰는데...
이해도 잘 안되고.. 어떻게 정리할지도 모르겠다. 위의 움짤이 그 결과물..
최적화 부분은 스킵해야겠다. 다음에 더 숙련되면 봐야지!

일단은 최적화 부분이랑 scss 부분만 빼고 봐야겠다. 아직 리액트랑 친해지는게 목표니깐..
복습이 필요할듯!


App.js

import React , {useState, useRef, useCallback} from 'react';
import TodoTemplate from './components/TodoTemplate';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';

const App =() => {
  const [todos,setTodos] = useState([
    {
      id:1,
      text:'리액트의 기초 알아보기',
      checked:true
    },
    {
      id:2,
      text:'컴포넌트 스타일링 해 보기',
      checked:true,
    },
    {
      id:3,
      text:'일정 관리 앱 만들어 보기',
      checked:false,
    }
  ])
  const nextId=useRef(4)
  const onInsert = useCallback(
    text => {
      const todo = {
        id: nextId.current,
        text,
        checked:false,
      }
      setTodos(todos.concat(todo));
      nextId.current+=1
    },[todos]
  )
  const onRemove = useCallback(
    id => {
      setTodos(todos.filter(todo => todo.id !== id))
    },[todos]
  )
  const onToggle = useCallback(
    id=>{
      setTodos(
        todos.map(todo=>
          todo.id === id ? {...todo, checked:!todo.checked}:todo)
      )
    },[todos],
  )
  return (
    <TodoTemplate>
      <TodoInsert onInsert={onInsert}/>
      <TodoList todos={todos} onRemove={onRemove} onToggle={onToggle}/>
    </TodoTemplate>
  )
}
export default App;

TodoTemplate.js

import React from 'react';
import './TodoTemplate.scss';

const TodoTemplate = ({children}) => {
    return (
        <div className="TodoTemplate">
            <div className="app-title">일정 관리</div>
            <div className="content">{children}</div>
        </div>
    )
}
export default TodoTemplate;

TodoInsert.js

import React , {useState,useCallback} from 'react';
import {MdAdd} from 'react-icons/md';
import './TodoInsert.scss';

const TodoInsert = ({onInsert}) => {
    const[value,setValue] = useState('');
    const onChange = useCallback(e=>{
        setValue(e.target.value)
    })
    const onSubmit = useCallback(
        e=> {
            onInsert(value);
            setValue('')
            e.preventDefault()
        },[onInsert,value]
    )

    return (
        <form className="TodoInsert" onSubmit={onSubmit}>
            <input 
                placeholder="할 일을 입력하세요."
                onChange={onChange}
                value={value}
            />
            <button type="submit">
                <MdAdd />
            </button>
        </form>
    )
}
export default TodoInsert;

TodoListItem.js

import React from 'react';
import {
    MdCheckBoxOutlineBlank,
    MdCheckBox,
    MdRemoveCircleOutline,
} from 'react-icons/md';
import cn from 'classnames';
import './TodoListItem.scss';

const TodoListItem = ({todo,onRemove,onToggle}) => {
    const {id, text, checked} = todo;
    return (
        <div className="TodoListItem">
            <div className="checkbox">
                <div className={cn('checkbox',{checked})} onClick={() => onToggle(id)}>
                    {checked ? <MdCheckBox/> : <MdCheckBoxOutlineBlank/>}
                    <div className="text">{text}</div>
                </div>
            </div>
            <div className="remove" onClick={() => onRemove(id)}>
                <MdRemoveCircleOutline/>
            </div>
        </div>
    )
}
export default TodoListItem;

TodoList.js

import React from 'react';
import TodoListItem from './TodoListItem';
import './TodoList.scss';

const TodoList = ({todos,onRemove,onToggle}) => {
    return (
        <div className="TodoList">
            {todos.map( todo => (
                <TodoListItem
                    todo={todo}
                    key={todo.id}
                    onRemove={onRemove}
                    onToggle={onToggle}
                />) ) }
        </div>
    )
}
export default TodoList;

기타 메모 :

props로 전달해야 할 함수를 만들 때는 useCallback을 사용하여 함수를 감싸는 걸 습관화하자

import cn from 'classnames'

...(생략)...

<div className={cn('checkbox',{checked})} />

위의 코드의 경우
checked 가 true 일때 className에 'checkbox'가 적용
checked 가 false 일때 className에 아무것도 적용X


immer

쓰기 전에 cmd에서 'yarn add immer' 를 입력해 설치해준다.

이 라이브러리는 불변성을 유지하는 작업을 매우 간단하게 처리할 수 있다.
'불변성에 신경 쓰지 않는 것처럼 코드를 작성하되 불변성 관리는 제대로 해주는 것'이 핵심!
첫 번째 파라미터에는 수정하고 싶은 상태!
두 번째 파라미터에는 상태를 어떻게 업데이트할지 정의하는 함수!

immer 사용 안할시 :

let nextObject = {
    ...object,
    somewhere: {
    	...object.somewhere,
        deep: {
            ...object.somewhere.deep,
            inside:4
        }
    }
};

(끔ㅡ찍)


immer 사용 할시 :

import produce from 'immer';

const nextState = produce(originalState, draft => {
    draft.somewhere.deep.inside = 5;

(편ㅡ안)

profile
흔한 컴공러 / 3학년

0개의 댓글