velopert / react-tutorial

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

21. 커스텀 Hooks 만들기 · GitBook #21

Open utterances-bot opened 4 years ago

utterances-bot commented 4 years ago

21. 커스텀 Hooks 만들기 · GitBook

https://react.vlpt.us/basic/21-custom-hook.html

angrybong commented 4 years ago

useInput.js에서 궁금한게 있습니다.

setForm(form => ({ ...form, [name]: value }));

이 코드에서... form => 저는 이것을 arrow function으로 생각해서 {{...form, [name]...로 생각했는데, 왜 괄호를 (로 감싸는건가요?

realopeningan commented 4 years ago

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/%EC%95%A0%EB%A1%9C%EC%9A%B0_%ED%8E%91%EC%85%98

위 싸이트에 답이 있네요(저도 왜그런가 몰라서 찾아봤어요..)

// 객체 리터럴 표현을 반환하기 위해서는 함수 본문(body)을 괄호 속에 넣음: params => ({foo: bar})

wealth99 commented 4 years ago

setForm(form => ({ ...form, [name]: value })); 저도 궁금해서 봤는데 위에 분 링크들어가서 보면 확인할 수 있듯 강의속에 나온 문법은 ES5 문법입니다. 풀어쓰자면
setFrom( (form) => function () { return { ...form, [name]: value }; }); 입니다.

GyuYoungLee commented 4 years ago

reset 때문에 onCreate 재사용이 안되네요. 아래처럼 deps 제거하니 해결되었어요 const reset = useCallback(() => setForm(initialForm), [initialForm]); => const reset = useCallback(() => setForm(inputs => Object.keys(inputs).reduce((acc, x) => ({ ...acc, [x]: '' }), {})), []);

dotdotgod commented 4 years ago

@zergcity 괄호를 안쓰면 인터프리터에서 함수 선언부로 인식해서 그렇습니다. 객체 반환으로 명시하기위해선 괄호를 써야합니다.

cloudbaby1991 commented 3 years ago

@dotdotgod 원래 함수형 업데이트를 할 때는 값을 리턴 해줘야 하는 건가요?

YoungkeunAhn commented 3 years ago

useInputs.js에서 setForm(form => ({ ...form, [name]: value })); 왜 form을 가져와서 ...form, [name]:value를 리턴한건가요

이전에는 setInputs를 할 땐 {...state, inputs:{...state,[name]:value)햇었자나요.

form이 객체 값이 아니라 함수라서 그런가요??

YoungkeunAhn commented 3 years ago

즉 setForm({...form, [name]:value})하면 input을 입력하고 다른 input을 입력하면 이전에 작성했던것이 reset되더라고요.

왜 이렇게 되는것인지를 알고 싶습니다.

dotdotgod commented 3 years ago

@YoungkeunAhn setForm(form => ({ ...form, [name]: value })); 에서 form은 prevState를 의미합니다.

useState 훅의 setState함수는 비동기라 실행 한 후 state값을 조회할 때 최신 state값의 반환을 보장하지 않습니다.

그렇기 때문에 이전 상태값이 업데이트될 상태값에 영향을 미치는 경우에 setState함수는 prevState를 인자로 받는 콜백을 받아 처리하는것을 권장합니다.

wenodev commented 3 years ago

커스텀 Hooks

sshusshu commented 2 years ago

커스텀 Hooks 를 만들어서 반복되는 로직을 쉽게 재사용

use 라는 키워드로 시작하는 파일을 만들고 그 안에 함수를 작성

그 안에서 useState, useEffect, useReducer, useCallback 등 Hooks 를 사용하여 원하는 기능을 구현해주고, 컴포넌트에서 사용하고 싶은 값들을 반환

yongyonghw commented 2 years ago

useInputs에서 dpes 부분 name, email 추가햇습니다.

ggsno commented 2 years ago

@YoungkeunAhn useCallback함수의 deps에 빈 배열을 전달했기 때문에 리렌더링 될 때마다 호출하게 됩니다. 이 때 dotdotgod님의 답변처럼 최신 state값을 보장하지 않기 때문에 현재 입력하고 있는 input을 제외한 나머지 값은 갱신이 되지 않은 채로 호출됩니다. 게시된 코드처럼 함수형 업데이트를 하지 않는다면 deps에 form을 추가해야 해당 버그가 사라집니다.

const onChange = useCallback((e) => {
    const {name, value} = e.target;
    setForm({...form, [name]: value});
}, [form]);
beng9re commented 2 years ago

안녕하세요. 리액트 입문한지 얼마 안되어 궁금한점이 생겨 코멘트 남기게 되었는데요

커스텀훅스의 역할이 반복되는 로직을 제거 하는 용도에서 사용한다라고 일단은 이해는 했는데 특정반복되는 로직을 제거하는 일반함수와 어떤 차이가 있지? 라는 생각이 들더라구요.

생각하기에는 리액트의 의존도(useState, useEffect)가 있는 함수가 있는 경우에 커스텀 훅스라고 생각되는데 이렇게 생각해도 될까요?

더 나아가서 이생각이 맞다면 의존도가 있는 함수만 use라는 키워드를 붙일수 있다. 라고 받아드려도 될련지 궁금합니다.

clean-teach commented 1 year ago

안녕하세요. 과제 : "useInput() Hook을 useReducer로 구현해보기" 에서 reset에 initialForm을 그대로 전달 해주면 안되나요?

case 'RESET' : 
       return action.initialForm;
const onReset = useCallback(() => (
        dispatch({type: 'RESET', initialForm})
 ), [initialForm]);