본문 바로가기
팀프로젝트_기록일지/React_이정환_context

(13).이정환_react.js강의_Context분리로 최적화 문제 해결

by 코잼민 2025. 1. 18.

★useMemo 복습하기 :

★ 분리법 + 구조파악

●TododispatchContext(함수 보관용 Context) , TodoStateContext(useState 변수 보관용 Context)

-순서1_ App 컴포넌트 밖에 Context 2개 초기화

import {createContext} from 'react';

const TodoStateContext = createContext();
const TodoDisPatchContext = createContext();

function App(){

}

-순서2_ DisPatch의 함수, 핸들러를 useMemo 등록하기

import {createContext} from 'react';

const TodoStateContext = createContext();
const TodoDisPatchContext = createContext();

function App(){

    const memorizedDispatch = useMemo(()=>{
        return {
            onCreateitem,
            onDeleteItem,
            onChangeIsDone
        }
    },[]);//핸들러 , 함수 호출 재생성 방지
    return (<div className="App">
    .
    .
    .
    </div>)

}

-순서3_ App 컴포넌트 return 내 태그에서 Context 태그 적절하게 감싸기

import {createContext} from 'react';

const TodoStateContext = createContext();
const TodoDisPatchContext = createContext();

function App(){

    const memorizedDispatch = useMemo(()=>{
        return {
            onCreateitem,
            onDeleteItem,
            onChangeIsDone
        }
    },[]);//핸들러 , 함수 호출 재생성 방지


  return (
    <div className="App">
      <Header />
         <TodoStateContext.provider value={items}>//context에 items 데이터들 담는 장면
            <TodoDispatchContext.Provider value={memorizedDispatch}>
                  <Editor />
                  <List items={items} />
             </TodoDispatchContext.Provider>
          </TodoStateContext.provider>

    </div>
  );

}

● Editor.js 에서는 onCreateItem을 TodoDisPatchContext에서 꺼내서 사용하기

-순서1_useContext와 TodoDisPatchContext를 import하여, 변수에 초기화

import {useContext} from 'react';
import {TodoDisPatchContext} from '../App.js';

const {onCreateItem} = useContext(TodoDisPatchContext);


function List(){

}

-순서2_Editor.js의 Props Drilling의 매개인자를 지우고, 꺼내서 태그 핸들러 속성에 적용

import {useContext} from 'react';
import {TodoDisPatchContext} from '../App.js';

const {onCreateItem} = useContext(TodoDisPatchContext);


function Editor(){

    return (<div className="Editor".
    .
    .

    <input
        ref={inputRef}
        onKeyDown={onKeyDownContent}
        value={input}
        onChange={onChangeContent}
        placeholder="새로운 Todo..."
      />
      <button onClick={onSubmit}>추가</button>
    </div>
    .
    .
    .
    .
    .

    </div>>)

}

● List.js에 TodoStateContext에서 items 꺼내 쓰기

import {useContext} from 'react';
import { TodoStateContext } from '../App.js';

const items = useContext(TodoStateContext);//객체로 저장 안되어있으므로, 그냥 저렇게 꺼내야함



function List(){

    return (<div className="List"
        .
        .
        .
        <div className="Lists">
            {getFilterItems.map((item) => {
                  return <TodoItem key={item.id} item={item} />;
            })}
          </div>
      //TodoItem 컴포넌트에 전달
      .
      .
      .

    </div>>)

}

● TodoItem.js에 TodoDisPatchContext에서 onChangeIsDone , onChangeIsDone 꺼내 쓰기

import {useContext} from 'react';
import {TodoDisPatchContext} from '../App.js';

const {onChangeIsDone , onDelete} = useContext(TodoDisPatchContext);

function TodoItem({item}){

   return (
    <div className="TodoItem">
      <input onChange={onChange} type="checkbox" checked={isDone} />
      <p className="TodoItem-title">{content}</p>
      <p className="TodoItem-date">{date.toLocaleDateString()}</p>
      <button onClick={onClickDelete}>삭제</button>
    </div>
  );
}

export default memo(TodoItem, (pProps, nProps) => {
  if (pProps.item.isDone !== nProps.item.isDone) return false;

  return true;
});