Frontend/React

React.js - contenteditable 사용시 발생하는 오류 해결

둉이 2023. 6. 8. 13:56

html 요소에 contenteditable 속성을 추가하면 input 요소처럼 수정이 가능한 요소를 만들 수 있다.

 

react에서는 contentEditable이라는 이름으로 props를 추가하면 된다.

 

하지만 실제로  요소에 contentEditable를 추가한 후 화면에서 텍스트를 수정해 보면 다음과 같은 warning이 발생한다.

Warning: A component is `contentEditable` and contains `children` managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.

 

내용을 해석해 보자면, 수정이 가능한 요소 내에 react에서 관리하는 children도 포함되어 있기 때문에 요소의 내용이 예기치 않게 수정되지 않도록 주의해 달라는 뜻이다.

 

요소를 수정함으로써 실제 dom과 react가 예측하는 dom의 내용과 달라지기 때문에, dom의 변경 사항 동기화에 문제가 생길 수도 있어 발생하는 경고이다.

 

 

 

해결 방법은 다음과 같다.

 

 

suppressContentEditableWarning 속성 추가

contentEditable과 함께 suppressContentEditableWarning={true} 속성을 넘겨주면 더이상 경고가 발생하지 않는다.

  return (
    <button
      id={id}
      contentEditable={isEditable}
      suppressContentEditableWarning
      onFocus={() => setIsEditable(true)}
      onBlur={() => setIsEditable(false)}
      {...restProps}
    >
      {text || PLACEHOLDER_TEXT}
    </button>
  );

 

 

react-contenteditable 사용

react-contenteditable은 react에서 오류 없이 contenteditable 속성을 쓸 수 있도록 지원하는 라이브러리이다.

 

GitHub - lovasoa/react-contenteditable: React component for a div with editable contents

React component for a div with editable contents. Contribute to lovasoa/react-contenteditable development by creating an account on GitHub.

github.com

 

 

다음과 같이 수정 가능 영역을 정의하여 사용할 수 있다.

import ContentEditable from 'react-contenteditable';

const EditableBox = () => {
  const ref = useRef(null);
  const [html, setHTML] = useState('<div>test</div>');

  return (
    <ContentEditable
      innerRef={ref}
      html={html}
      onChange={({ target }) => setHTML(target.value)}
    />
  );
};

export default EditableBox;

 

 

console.error 함수 내용 수정

직접 수동으로 console.error 함수 내에 조건을 수정하여 경고를 발생하지 않도록 하는 방법도 있다.

  useEffect(() => {
    console.error = (function (_error) {
      return function (message, ...args) {
        if (
          typeof message !== 'string' ||
          message.indexOf('component is `contentEditable`') === -1
        ) {
          _error.apply(console, args);
        }
      };
    })(console.error);
  }, []);

 

 

 

참고 링크

 

A component is `contentEditable` and contains `children` managed by React warning · Issue #81 · facebookarchive/draft-js

When integrating draft-js into an existing project I get Warning: A component is contentEditable and contains children managed by React. It is now your responsibility to guarantee that none of thos...

github.com