[react] useState 비동기

woo·2022년 8월 29일
0

기능 구현

목록 보기
9/17

문제가 발생해 찾던 중 useState가 비동기로 작동하기 때문이라는 결론이 나와서 이 부분을 더 공부해보려고 적는 글!

😨 문제코드

function BlogUpdate() {
    const [BlogUpdateForm, setBlogUpdateForm] = useState({
        title: '',
        content: '',
    });

    const onChange = (e) => {
        const { value, name } = e.target;
        setBlogUpdateForm({ ...BlogUpdateForm, [name]: value });
    };

    const updateBlog = async () => {
        if (checkVaildation()) {
			// 성공시 api
        } else {
            rejectAlert();
        }
    };

    useEffect(async () => {
        const blog = await getBlog(BlogId);
        setBlogUpdateForm({
            ...BlogUpdateForm,
            title: blog.title,
            content: blog.content,
        });
    }, []);

    return (
        <Panel>
      		<TitleInput
            	type="text"
            	name="title"
                id="title"
            	value={BlogUpdateForm.title}
            	onChange={onChange}
            	placeholder="제목을 입력해주세요"
            />
            <EditorWrapper>
                <CKEditor
                    editor={ClassicEditor}
                    config={editorConfiguration}
                    data={BlogUpdateForm.content}
                    onChange={(event, editor) => {
                    const data = editor.getData();
                      setBlogUpdateForm({ ...BlogUpdateForm, content: data });
                      }}
                  />
             </EditorWrapper>
                <UpdateButton onClick={updateBlog}>수정하기</UpdateButton>
        </Panel>
    );
}

useEffect로 작동할때 비동기로 api를 불러와 그 결과값을 blog에 저장한다. 그리고 그 결과를 setBlogUpdateForm으로 BlogUpdateForm안에 기존에 있던 데이터를 추가해 사용자에게 보여주는 방식이다.

문제는 아래에 CKEditor를 사용 부분에서 CKEditor에 입력되어있는 data를 BlogUpdateForm에 넣는데 이 과정에서 BlogUpdateForm에는 아직 useEffect가 적용되지 않는 초기화 상태이기 때문에 계속 title에 값이 들어가지 않는 것처럼 보인다.

            <EditorWrapper>
                <CKEditor
                    editor={ClassicEditor}
                    config={editorConfiguration}
                    data={BlogUpdateForm.content}
                    onChange={(event, editor) => {
                    const data = editor.getData();
                      // 이부분에서 useState가 비동기를 작동하기 때문에 
                      // 위에서 useEffect로 useState가 반영되지 않은 
                      // 초기화 상태인 BlogUpdateForm를 
                      // setState로 넣기 때문에 
                      // 마지막 setState만 반영되어 사실상 아무런 값도 들어가지 않는것!
                      setBlogUpdateForm({ ...BlogUpdateForm, content: data });
                      }}
                  />

🛠 해결

            <EditorWrapper>
                <CKEditor
                    name="conference_create_editor"
                    editor={ClassicEditor}
                    config={editorConfiguration}
                    data={BlogUpdateForm.content}
                    onChange={(event, editor) => {
                    const data = editor.getData();
                           // 화살표함수를 이용하여
                           // 동기적으로 작동시킴
                           // 즉, 위에서 useState로 바뀐 인자를 넘겨준다.
                            setBlogUpdateForm((BlogUpdateForm) => {
                              return {
                                  ...BlogUpdateForm,
                                  content: data,
                              };
                          });
                      }}
                  />
             </EditorWrapper>

참고 글

profile
🌱 매일 성장하는 개발자

0개의 댓글