velopert / react-tutorial

벨로퍼트와 함께하는 모던 리액트 튜토리얼 문서
https://react.vlpt.us/
347 stars 100 forks source link

2. Context API를 활용한 상태 관리 · GitBook #24

Open utterances-bot opened 4 years ago

utterances-bot commented 4 years ago

2. Context API를 활용한 상태 관리 · GitBook

https://react.vlpt.us/mashup-todolist/02-manage-state.html

2myungho commented 4 years ago

패스트캠퍼스로 강의를 듣고 있습니다!

export function TodoProvider({ children }) { const [state, dispatch] = useReducer(todoReducer, initialTodos); return children; } 이부분에 export부분에 기본형으로 밖에 본적이 없어서 이해가 잘 안되는데 추가 설명 있는 영상이 있을까요..?

jinsugoda commented 4 years ago

Hook을 사용하기전 TodoContext 에서 const TodoStateContext = createContext(); const TodoDispatchContext = createContext();

여기서 export 를 해주어야 하지 않습니까? 그리고 전글에서도 질의를 하였지만 children props 를 왜 주어야 하며 이름을 children으로 주지 않으면 즉 다른 이름으로 주면 제대로 동작하지 않습니다. 여기에 대하여 설명을 부탁드립니다.

Conradmaker commented 4 years ago

TodoStateContext나 TodoDispatchContext를 export하지 않는 이유는 외부에서 이둘을 호출하는게 아니라 밑에서 useContext를 만들어 그 훅을 외부에서 호출하기 때문이죠.. children Props의 경우에는 기본편JSX설명하실때 이미 설명해주신 부분입니다. APP component에서 component들을 TodoProvider를 통해 감싸주기 때문에 그 안에 있는 컴포넌트들이 적용되기위해서는 children props를 넣어주어야 감싸진 component들이 적용되게 되는걸로 알고있습니다.

ypyp66 commented 3 years ago

@jinsugoda 예약어입니다

HandsomeChoco commented 3 years ago

@2myungho export default 를 사용하면 다른 파일에서 불러올 때 import 함수이름 으로 불러올 수 있습니다. default 가 빠지면 import { 함수이름 } 이렇게 불러와야 헙니다. 즉 export default 한 함수는 import 시 {} 가 필요 없습니다.

hoooodboy commented 3 years ago

function todoReducer(state, action){ switch(action.type){ case 'CREATE': return state.concat(action.todo); case 'TOGGLE': return state.map(todo => todo.id === action.id ? {...todo, done: !todo.done}: todo) case 'REMOVE': return state.filter(todo => todo.id !== action.id) default:

        throw new Error("ERROR");
}

}

.todo는 어디서 튀어나온건가요..?

cloudbaby1991 commented 3 years ago

아래의 코드가 가장 헷갈리는데요

if문으로 context를 체크하는건 정확하게 어떤 원리인건지 모르겠습니다.

감싸져있는걸 저렇게 체크 할 수 있나요?

export function useTodoState() { const context = useContext(TodoStateContext); if (!context) { throw new Error("Cannot find TodoProvider"); }

return context; }

HandsomeChoco commented 3 years ago

@cloudbaby1991 Provider 바깥에서 컨텍스트를 사용하려면 에러가 뜹니다 그러면 잘못된 곳에서 함수를 호출했구나를 알 수 있어요,

cloudbaby1991 commented 3 years ago

@HandsomeChoco 즉 안에 컴포넌트들이 존재하니 해당 범위에서 호출하지 않으면 에러가 발생한다는 것으로 이해하면 될까요?

HandsomeChoco commented 3 years ago

한번 Provider 바깥에 위치하는 컴포넌트에서 useTodoState 함수를 불러와서 state 를 렌더링 하려고 해보세요. 그 때 에러가 뜨게 되는데, 무슨 말인지 이해가 되실 겁니다!

cgy0915 commented 3 years ago

저도 031hoodboy 님과 같은 질문인데요, 저부분에 대해서 혹시 설명 좀 부탁 드립니다! 혹시 아니면 참고 할만한 블로그라도 좀 알 수 있을까요?

function todoReducer(state, action) {
  switch (action.type) {
    case "CREATE":
      return state.concat(action.todo);
    case "TOGGLE":
      return state.map((todo) =>
        todo.id === action.id ? { ...todo, done: !todo.done } : todo
      );
    case "REMOVE":
      return state.filter((todo) => todo.id !== action.id);
    default:
      throw new Error(`Unhandled action type: ${action.type}`);
  }
}

todo 가 어디서 나온건지?

ypyp66 commented 3 years ago

@cgy0915 initialState안의 항목들을 todo라고 한거에요

chaenabi commented 3 years ago

@cgy0915 @031hoodboy case "TOGGLE": state.map((sasdafs) => { sasdafs.id === action.id ? { ...sasdafs, done: !sasdafs.done } : sasdafs } 이렇게 안의 todo 변수 자체는 아무런 이름(sasdafs 처럼)으로 치환해도 됩니다. 이름은 개발자가 정하기 나름이고 가독성 외에는 크게 중요하지 않지만, 안에 든 값은 중요합니다. sadafs 안에 들어있는 값들은 map 함수에 의해 state 배열 내의 객체 하나하나들({id:1, text: '프로젝트 생성하기', done: false} 등)을 처음부터 순차적으로 순회하면서 작업됩니다.

GEUNWOOAHN commented 1 year ago

현재는 아래와 같이 State 안에 Dispatch 안에 NextId 이렇게 되어 있는데요~~!

{children} 이 부분의 순서는 상관없나요...?