[reactjs] react js에서 onchange 이벤트를 트리거하는 가장 좋은 방법은 무엇입니까?
Backbone + ReactJS 번들을 사용하여 클라이언트 측 앱을 빌드합니다. 악명 높은 것에 크게 의존하여 valueLink
양방향 바인딩을 위해 ReactJS 인터페이스를 지원하는 자체 래퍼를 통해 모델에 직접 값을 전파합니다.
이제 우리는 문제에 직면했습니다.
우리는이 jquery.mask.js
프로그램 따라서 화재 이벤트를 반응하지 않는 입력 값의 형식을 플러그인. 이 모든 것이 모델이 사용자 입력에서 형식화되지 않은 값을 수신 하고 플러그인 에서 형식화 된 값을 놓치는 상황으로 이어집니다 .
React는 브라우저에 따라 많은 이벤트 처리 전략을 가지고있는 것 같습니다. React가 그것을 듣도록 특정 DOM 요소에 대한 변경 이벤트를 트리거하는 일반적인 방법이 있습니까?
답변
React 16 및 React> = 15.6의 경우
.value=
React 라이브러리가 입력 값 setter를 재정의하기 때문에 Setter 가 원하는대로 작동하지 않지만 input
as 컨텍스트 에서 직접 함수를 호출 할 수 있습니다 .
var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
nativeInputValueSetter.call(input, 'react 16 value');
var ev2 = new Event('input', { bubbles: true});
input.dispatchEvent(ev2);
textarea 요소 prototype
의 경우 HTMLTextAreaElement
클래스 를 사용해야합니다 .
새로운 코드 펜 예제 .
React <= 15.5에 대한 오래된 답변
으로 react-dom ^15.6.0
당신이 사용할 수있는 simulated
이벤트가 통과하는 이벤트 객체에 플래그를
var ev = new Event('input', { bubbles: true});
ev.simulated = true;
element.value = 'Something new';
element.dispatchEvent(ev);
새 플래그가 필요한 이유를 이해하기 위해이 주석이 매우 유용 하다는 것을 알았습니다 .
React의 입력 로직은 이제 값당 두 번 이상 발생하지 않도록 변경 이벤트의 중복을 제거합니다. 브라우저 onChange / onInput 이벤트와 DOM 노드 값 소품 (JavaScript를 통해 값을 업데이트 할 때)에 대한 설정을 모두 수신합니다. 이것은 입력 값을 수동으로 업데이트하면 input.value = ‘foo’다음 {target : input}과 함께 ChangeEvent를 전달한다는 의미의 부작용이 있습니다. React는 세트와 이벤트를 모두 등록합니다. 값이 여전히` ‘foo인지 확인합니다. ‘, 중복 이벤트로 간주하고 삼키십시오.
이것은 “실제”브라우저에서 시작된 이벤트가 element.value에 대한 집합을 트리거하지 않기 때문에 정상적인 경우에 잘 작동합니다. 시뮬레이션 된 플래그로 트리거 한 이벤트에 태그를 지정하여이 논리를 비밀리에 탈출 할 수 있으며 반응은 항상 이벤트를 발생시킵니다.
https://github.com/jquense/react/blob/9a93af4411a8e880bbc05392ccf2b195c97502d1/src/renderers/dom/client/eventPlugins/ChangeEventPlugin.js#L128
답변
적어도 텍스트 입력에서는 onChange
입력 이벤트를 수신 하는 것처럼 보입니다 .
var event = new Event('input', { bubbles: true });
element.dispatchEvent(event);
답변
이 답변이 조금 늦게 오는 것을 알고 있지만 최근 비슷한 문제에 직면했습니다. 중첩 된 구성 요소에서 이벤트를 트리거하고 싶었습니다. 라디오 및 체크 박스 유형 위젯 (체크 박스 및 / 또는 라디오 버튼처럼 작동하는 div)이 포함 된 목록이 있었고 애플리케이션의 다른 위치에 누군가가 도구 상자를 닫으면 하나를 선택 취소해야했습니다.
나는 이것이 모범 사례인지 확실하지 않지만 매우 간단한 해결책을 찾았지만 작동합니다.
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': false
});
var node = document.getElementById('nodeMyComponentsEventIsConnectedTo');
node.dispatchEvent(event);
이것은 domNode에서 클릭 이벤트를 트리거하고 react를 통해 연결된 핸들러가 실제로 호출되었으므로 누군가가 요소를 클릭하면 예상하는 것처럼 작동합니다. 나는 onChange를 테스트하지 않았지만 작동해야하며 이것이 실제로 오래된 버전의 IE에서 어떻게 공정 할 지 확실하지 않지만 MouseEvent는 적어도 IE9 이상에서 지원된다고 생각합니다.
내 구성 요소가 매우 작기 때문에 (내 응용 프로그램의 일부만 반응을 사용했기 때문에 (아직 배우고 있기 때문에) dom 노드에 대한 참조를 얻지 않고도 다른 방식으로 동일한 것을 달성 할 수 있었기 때문에 특정 사용 사례에서 결국이에서 멀어졌습니다.
최신 정보:
다른 사람들이 주석에서 언급했듯이 this.refs.refname
dom 노드에 대한 참조를 얻는 데 사용하는 것이 좋습니다 . 이 경우 refname은를 통해 구성 요소에 연결 한 참조 <MyComponent ref='refname' />
입니다.
답변
ReactTestUtils를 사용하여 이벤트를 시뮬레이션 할 수 있습니다. 있지만 이는 단위 테스트 용으로 설계되었습니다.
이 경우 valueLink를 사용하지 않고 플러그인에 의해 발생한 변경 이벤트를 수신하고 이에 대한 응답으로 입력 상태를 업데이트하는 것이 좋습니다. 양방향 바인딩은 다른 무엇보다 데모로 더 유용합니다. 순수한 양방향 바인딩이 대부분의 응용 프로그램에 적합하지 않으며 일반적으로 앱의 상호 작용을 설명하기 위해 더 많은 응용 프로그램 논리가 필요하다는 사실을 강조하기 위해 애드온에 포함됩니다.
답변
Grin / Dan Abramov의 답변을 확장하면 여러 입력 유형에서 작동합니다. React> = 15.5에서 테스트 됨
const inputTypes = [
window.HTMLInputElement,
window.HTMLSelectElement,
window.HTMLTextAreaElement,
];
export const triggerInputChange = (node, value = '') => {
// only process the change on elements we know have a value setter in their constructor
if ( inputTypes.indexOf(node.__proto__.constructor) >-1 ) {
const setValue = Object.getOwnPropertyDescriptor(node.__proto__, 'value').set;
const event = new Event('input', { bubbles: true });
setValue.call(node, value);
node.dispatchEvent(event);
}
};
답변
임의의 요소에 대한 변경 이벤트를 트리거하면 추론하기 어려운 구성 요소간에 종속성이 생성됩니다. React의 단방향 데이터 흐름을 고수하는 것이 좋습니다.
React의 변경 이벤트를 트리거하는 간단한 스 니펫은 없습니다. 로직은 ChangeEventPlugin.js에서 구현되며 다양한 입력 유형 및 브라우저에 대해 서로 다른 코드 분기가 있습니다. 또한 구현 세부 사항은 React 버전에 따라 다릅니다.
나는 일을하는 react-trigger-change 를 만들었지 만 프로덕션 종속성이 아닌 테스트에 사용하도록 의도되었습니다.
let node;
ReactDOM.render(
<input
onChange={() => console.log('changed')}
ref={(input) => { node = input; }}
/>,
mountNode
);
reactTriggerChange(node); // 'changed' is logged
답변
onchange 이벤트를 처리하기 위해 함수를 사용하기 때문에 다음과 같이 할 수 있습니다.
class Form extends Component {
constructor(props) {
super(props);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.state = { password: '' }
}
aForceChange() {
// something happened and a passwordChange
// needs to be triggered!!
// simple, just call the onChange handler
this.handlePasswordChange('my password');
}
handlePasswordChange(value) {
// do something
}
render() {
return (
<input type="text" value={this.state.password} onChange={changeEvent => this.handlePasswordChange(changeEvent.target.value)} />
);
}
}