인프런 커뮤니티 질문&답변

sshssh님의 프로필 이미지
sshssh

작성한 질문수

웹 게임을 만들며 배우는 React

2-1. React Hooks 사용하기

안녕하세요 setState 관련 질문입니다.

작성

·

1.6K

0

강의를 보고 setState를 이것 저것 해보는 와중에 이해가 안되는 부분이 생겨 여쭤봅니다.

input 박스에 입력할 때, 최초 입력 할 땐 맨앞에 공백을 추가 해서 setState 를 하고 그 이후에는 입력한값으로만 setState 하려 하는데, 한글이 중복으로 입력 되는 상황이 발생 합니다.

예를들어 "가" 를 입력한다면

1) " ㄱ"

2) " 가" 

를 예상하는데, 실제로는 

1) " ㄱ"

2) " ㄱ가"

가 출력 됩니다...

 

코드도 첨부합니다. 

 

import "./App.css";
import { useEffect, useRef, useState } from "react";

function App() {
  const [inputVal, setInputVal] = useState("");
  const ref = useRef(inputVal);

  const handleChange = (e) => {
    if (ref.current.length === 0) {
      setInputVal(" " + e.target.value);
    } else {
      setInputVal(e.target.value);
    }
  };

  useEffect(() => {
    ref.current = inputVal;
  }, [inputVal]);

  return (
    <div className="App">
      <input value={inputVal} onChange={handleChange} />
    </div>
  );
}

export default App;

 

이유를 알 수 있을까요?

 

 

답변 2

0

한글은 다른 알파벳 문자랑 달리 글자 입력을 모아주는 composition 과정이 있어서 그걸 확인해야 할겁니다. 이 문서 참고해보세요. https://stackoverflow.com/questions/35876470/react-composition-events

sshssh님의 프로필 이미지
sshssh
질문자

답변 감사합니다.

 

말씀해주신 부분 찾아봤는데 제가 의도한대로 작동했다면 start->update->update 가 맞는데,

start가 또 출력 되는걸로 보니 잘못된것 같네요... end 도 안찍히고...

 

방법이 없을까요 ? 혹시 몰라 코드 첨부 해봅니다..

 

import "./App.css";

import { useEffect, useRef, useState } from "react";

function App() {
  const [inputVal, setInputVal] = useState("");
  const [whiteSpaceFlag, setWhiteSpaceFlag] = useState(true);
  const ref = useRef(inputVal.length);

  const handleChange = (e) => {
    const { value } = e.currentTarget;
    if (value === "" && !whiteSpaceFlag) {
      setWhiteSpaceFlag(true);
    }

    // ref.current;
    if (ref.current === 0 && whiteSpaceFlag) {
      setWhiteSpaceFlag(false);
      setInputVal(" " + value);
    } else {
      setInputVal(value);
    }
  };

  useEffect(() => {
    ref.current = inputVal.length;
  });

  const onCompositionStart = (e) => {
    console.log("start", e.data);
  };

  const onCompositionUpdate = (e) => {
    console.log("update", e.data);
  };

  const onCompositionEnd = (e) => {
    console.log("end", e.data);
  };

  return (
    <div className="App">
      <input
        value={inputVal}
        onInput={handleChange}
        onCompositionStart={onCompositionStart}
        onCompositionUpdate={onCompositionUpdate}
        onCompositionEnd={onCompositionEnd}
      />
    </div>
  );
}

export default App;

 

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

ref.current를 왜 하셨나요? 앞에 띄어쓰기를 넣고 싶으시면 그냥 첫 글자가 띄어쓰기가 아닌 경우 " "를 붙여주는 setInputVal를 하시면 됩니다.

sshssh님의 프로필 이미지
sshssh
질문자

ref로 최초로 입력되는 시점을 잡으려고 썼습니다.

 

'첫 글자가 띄어쓰기가 아닌경우 " " 를 붙여주는 setInputVal' 이란걸

이런식으로 짜봤는데 결과는 동일하네요.. 어디가 문제일까요?

한글 자음과 모음이 합쳐지는 부분만 문제가 발생합니다. 영어나, 자음으로만 된 문자열은 문제가 발생하지 않습니다.

import "./App.css";

import { useState } from "react";

function App() {
  const [inputVal, setInputVal] = useState("");

  const handleChange = (e) => {
    const { value } = e.currentTarget;
    if (value.substring(0, 1) !== " ") {
      setInputVal(" " + value);
    } else {
      setInputVal(value);
    }
  };

  return (
    <div className="App">
      <input value={inputVal} onChange={handleChange} />
    </div>
  );
}

export default App;
제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

음, 그럼 제 추측은 '리액트'를 쳤을 때 처음 ㄹ에서 벌써  ' ㄹ'이 되어버린 건 아닌지 의심됩니다.

일단 먼저 onChange 대신 onInput 도 한 번 해보세요.

sshssh님의 프로필 이미지
sshssh
질문자

onInput 도 동일합니다.

 

'리액트'를 쳤을 때 처음 ㄹ에서 벌써  ' ㄹ'이 되어버린 건 아닌지 의심

 

저도 이렇게밖에 생각이 되지 않습니다...

 

다른 변수 값을 둬서 공백이 있는것 처럼 처리는 했는데 근본적인 문제 해결은 아닌거 같아 여쭤봤습니다ㅠㅠ

 

이러한 경우는 어쩔수 없이 다른 방식을 쓰는게 맞는걸까요 ?

 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

저는 onChange할때 안하고 그 값을 onSubmit한다든가 할 때 띄어쓰기를 붙일 것 같긴 합니다.

sshssh님의 프로필 이미지
sshssh

작성한 질문수

질문하기