[React] ClickToEdit Component

걸음걸음·2023년 2월 22일
0

React

목록 보기
5/9

Click to Edit

input창을 클릭하면 수정이 가능하고 다른 곳을 클릭하면 수정한 내용이 반영되는 컴포넌트

의사코드

  1. span을 클릭하면 input으로 전환, input을 벗어나면 span으로 전환
  2. true/false 관리할 useState 생성
  3. onClick, onBlur 이벤트가 발생했을 때 boolean값 변경하는 함수 실행
  4. onBlur 이벤트 발생시 input에 입력한 값을 업데이트해 span에 전달

코드

export const MyInput = ({ value, handleValueChange }) => {
  const inputEl = useRef(null);
  const [isEditMode, setEditMode] = useState(false);
  const [newValue, setNewValue] = useState(value);

  useEffect(() => {
    if (isEditMode) {
      inputEl.current.focus();
    }
  }, [isEditMode]);

  useEffect(() => {
    setNewValue(value);
  }, [value]);

  const handleClick = () => {
    setEditMode(true);
  };

  const handleBlur = () => {
    handleValueChange(newValue);
    setEditMode(false);
  };

  const handleInputChange = (e) => {
    setNewValue(e.target.value);
  };

  return (
    <div>
      {isEditMode ? (
        <input
          type='text'
          value={newValue}
          ref={inputEl}
          onBlur={handleBlur}
          onChange={handleInputChange}
        />
      ) : (
        <span onClick={handleClick}>{newValue}</span>
      )}
    </div>
  );
};

const cache = {
  name: '이름을 입력하세요',
  age: 0,
};

export const ClickToEdit = () => {
  const [name, setName] = useState(cache.name);
  const [age, setAge] = useState(cache.age);

  return (
    <>
      <div>
        <label>이름</label>
        <MyInput
          value={name}
          handleValueChange={(newValue) => setName(newValue)}
        />
      </div>
      <div>
        <label>나이</label>
        <MyInput
          value={age}
          handleValueChange={(newValue) => setAge(newValue)}
        />
      </div>
      <div>
        <div className='view'>
          이름 {name} 나이 {age}
        </div>
      </div>
    </>
  );
};

기억할 것

focus

사용자가 폼 요소를 클릭하거나 [tab]키를 눌러 요소로 이동하면 해당 요소가 포커스(focus)
주로 데이터 입력 준비를 의미, 포커싱이 이루어지는 순간 초기화 코드 실행 가능
autofocus : 페이지가 로드된 후 자동으로 해당 요소 포커싱

blur

요소가 포커스를 잃는 순간
주로 데이터 입력이 완료되었음을 의미, 데이터 체크 및 데이터 저장 서버 요청 등을 실행

메소드

elem.focus() 와 elem.blur() 메서드를 사용해 요소에 포커스를 줄 수도, 제거할 수도 있음
올바르지 못한 값이 입력되었을 경우, onblur 메서드가 동작해 포커스를 다시 입력필드로 돌려놓을 수 있음

  • focus 이벤트는 버블링되지 않음.
    이 경우 캡쳐링이나 focusin, focusout을 사용하면 이벤트 위임효과를 볼 수 있음

  • 대부분의 요소는 기본적으로 포커스를 지원하지 않음. 그럼에도 포커스 하고 싶은 요소가 있다면 tabindex 사용 가능.

profile
꾸준히 나아가는 개발자입니다.

0개의 댓글