[javascript] React에서 onChange와 onInput의 차이점은 무엇입니까?

나는 이것에 대한 답을 찾기 위해 노력했지만 대부분은 onChange흐림을 유발하는 React의 컨텍스트 외부에 있습니다 .

다양한 테스트를 수행 할 때이 두 이벤트가 어떻게 다른지 (텍스트 영역에 적용했을 때) 말할 수없는 것 같습니다. 누구든지 이것에 대해 밝힐 수 있습니까?



답변

진짜 차이가없는 것 같아요

어떤 이유로 React는 리스너를 Component.onChangeDOM element.oninput이벤트에 연결합니다. 양식에 대한 문서의 참고를 참조하십시오.

React 문서-양식

이 행동에 놀라는 사람들이 더 많이 있습니다. 자세한 내용은 React 문제 추적기에서이 문제를 참조하세요.

React의 onChange가 onInput # 3964와 어떻게 관련되는지 문서화

해당 문제에 대한 의견에서 인용 :

React가 onChange가 onInput처럼 동작하도록 선택한 이유를 이해할 수 없습니다. 내가 알 수 있듯이, 우리는 이전 onChange 동작을 되돌릴 방법이 없습니다. 문서는 이것이 “잘못된 명칭”이라고 주장하지만 실제로는 아닙니다. 입력이 포커스를 잃을 때까지 변경 사항이있을 때 실행됩니다.

유효성 검사를 위해 입력이 완료 될 때까지 유효성 검사 오류를 표시하지 않으려는 경우가 있습니다. 아니면 모든 키 입력에 대해 다시 렌더링하는 것을 원하지 않을 수도 있습니다. 이제이를 수행하는 유일한 방법은 onBlur를 사용하는 것이지만 이제는 값이 수동으로 변경되었는지도 확인해야합니다.

그렇게 큰 거래는 아니지만 React가 유용한 이벤트를 버리고 이미 이것을 수행하는 이벤트가 있었을 때 표준 동작에서 벗어난 것처럼 보입니다.

댓글에 100 % 동의합니다 …하지만 지금 변경하면이 동작에 의존하는 많은 코드가 이미 작성 되었기 때문에 해결하는 것보다 더 많은 문제가 발생할 것 같습니다.

React는 공식 Web API 컬렉션의 일부가 아닙니다.

React가 JS를 기반으로 구축되고 엄청난 채택률을 보였음에도 불구하고 React는 자체 (상당히 작은) API 아래에 많은 기능을 숨기기 위해 존재하기 때문입니다. 이것이 명백한 영역은 이벤트 시스템에 있으며, 표면 아래에서 실제로는 표준 DOM 이벤트 시스템과 근본적으로 다른 많은 일이 진행되고 있습니다. 어떤 이벤트가 무엇을하는지뿐만 아니라 데이터가 이벤트 처리의 어떤 단계에서 지속될 수 있도록 허용되는 경우도 마찬가지입니다. 여기에서 자세한 내용을 읽을 수 있습니다.

반응 이벤트 시스템


답변

다른 점이 없다

React에는 기본 ‘onChange’이벤트의 동작이 없습니다. 우리가 반응에서 보는 ‘onChange’는 기본 ‘onInput’이벤트의 동작을 가지고 있습니다. 따라서 귀하의 질문에 대답하기 위해 반응에서 두 가지 모두 차이가 없습니다. 나는 GitHub에서 동일한 문제를 제기했으며 이것이 그들이 그것에 대해 말해야하는 것입니다.

이 결정이 내려 졌을 때 (~ 4 년 전?) onInput은 브라우저간에 일관되게 작동하지 않았고 다른 플랫폼에서 웹을 방문하는 사람들에게 혼란 스러웠습니다. 모든 변화에 불이 붙습니다. React의 경우 변경 사항을 빨리 처리하지 못하면 제어 된 입력이 업데이트되지 않아 사람들이 React가 손상되었다고 생각하게되므로 더 큰 문제입니다. 그래서 팀은 그것을 onChange라고 불렀습니다.

돌이켜 보면 다른 이벤트의 동작을 변경하는 것보다 onInput을 폴리 필하고 이름을 유지하는 것이 더 나은 생각이었을 것입니다. 하지만 그 배는 오래 전에 항해했습니다. 나중에이 결정을 다시 검토 할 수도 있지만, React DOM의 특성으로 취급하는 것이 좋습니다 (아주 빨리 익숙해 질 것입니다).

https://github.com/facebook/react/issues/9567

또한이 기사는 더 많은 통찰력을 제공 할 것입니다. 기본 ‘onChange’누락에 대한 해결 방법으로이 기사에서는 ‘onBlur’이벤트 수신을 제안합니다.

https://www.peterbe.com/plog/onchange-in-reactjs


답변

최근 onChange에 IE11의 입력 필드에 복사 및 붙여 넣기를 허용하지 않는 버그가 있습니다. onInput이벤트가 그 행동을 허용하는 반면 . 문서에서 이것을 설명하는 문서를 찾을 수 없지만 둘 사이에 차이가 있음을 보여줍니다 (예상 여부).


답변

여기의 다양한 주석에서 볼 수 있듯이 React는이 결정의 장점에 대해 토론하기보다는 onChange와 onInput을 동일하게 취급합니다. 여기에 해결책이 있습니다.

완료 될 때까지 사용자의 편집을 처리하지 않으려면 onBlur를 사용하십시오. 🙂


답변

실제 DOM 기반 change이벤트 를 수신하는 방법을 찾고있는이 문제를 우연히 발견 한 사람은 다음 과 같이합니다 (TypeScript로 작성).

import { Component, createElement, InputHTMLAttributes } from 'react';

export interface CustomInputProps {
    onChange?: (event: Event) => void;
    onInput?: (event: Event) => void;
}

/**
 * This component restores the 'onChange' and 'onInput' behavior of JavaScript.
 *
 * See:
 * - https://reactjs.org/docs/dom-elements.html#onchange
 * - https://github.com/facebook/react/issues/3964
 * - https://github.com/facebook/react/issues/9657
 * - https://github.com/facebook/react/issues/14857
 */
export class CustomInput extends Component<Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'onInput' | 'ref'> & CustomInputProps> {
    private readonly registerCallbacks  = (element: HTMLInputElement | null) => {
        if (element) {
            element.onchange = this.props.onChange ? this.props.onChange : null;
            element.oninput = this.props.onInput ? this.props.onInput : null;
        }
    };

    public render() {
        return <input ref={this.registerCallbacks} {...this.props} onChange={undefined} onInput={undefined} />;
    }
}

이 접근 방식을 개선하는 방법을 보거나 문제가 발생하면 알려주십시오. 달리가 blurchange사용자 프레스는 입력 값이 실제로 변경 한 경우에만 트리거 될 때 이벤트는 트리거됩니다.

나는 여전히이 CustomInput구성 요소에 대한 경험을 얻고 있습니다 . 예를 들어 체크 박스가 이상하게 작동합니다. 값을 확인란에 전달하는 동안 처리기 event.target.checked에서 반전하거나 onChange값을 확인란에 checked전달할 때이 반전을 제거해야 defaultChecked하지만이 경우 페이지의 다른 위치에서 동일한 상태를 나타내는 여러 확인란이 동기화 상태로 유지됩니다. . (두 경우 모두 for 확인란에 onInput핸들러를 전달하지 않았습니다 CustomInput.)


답변

한 가지 차이점은 onChange동일한 캐릭터를 가진 캐릭터를 선택하고 교체 할 때 발생하지 않는 반면에있는 onInput것 같습니다.

이 샌드 박스를 참조하십시오 : https://codesandbox.io/s/react-onchange-vs-oninput-coggf?file=/src/App.js

  • 필드에 “A”를 입력 한 다음 모두 선택하고 “B”를 입력합니다. 이것은 4 개의 이벤트, 2 onChange및 2를 트리거합니다 onInput.
  • 이제 모두를 선택하고 “B”를 다시 입력합니다. 이렇게하면 새 onInput이벤트가 트리거 되지만 onChange.


답변