나는 CustomEvent
부모 노드와 통신하기 위해 일반 DOM을 만들고 듣고 있습니다 .
어린이 :
var moveEvent = new CustomEvent('the-graph-group-move', {
detail: {
nodes: this.props.nodes,
x: deltaX,
y: deltaY
},
bubbles: true
});
this.getDOMNode().dispatchEvent(moveEvent);
부모 :
componentDidMount: function () {
this.getDOMNode().addEventListener("the-graph-group-move", this.moveGroup);
},
이것은 작동하지만 더 나은 React 전용 방법이 있습니까?
답변
위에서 언급 한대로 :
React 방식은 props를 통해 명시 적으로 자식에게 콜백을 전달하는 것입니다. React에서 버블 링이있는 사용자 지정 이벤트는 지원되지 않습니다.
반응 형 프로그래밍 추상화는 직교합니다.
관찰자 패턴을 사용하여 대화 형 시스템을 프로그래밍하는 것은 어렵고 오류가 발생하기 쉽지만 여전히 많은 프로덕션 환경에서 구현 표준입니다. 우리는 반응 형 프로그래밍 추상화를 위해 관찰자를 점차적으로 비난하는 접근 방식을 제시합니다. 여러 라이브러리 레이어는 프로그래머가 기존 코드를 콜백에서보다 선언적인 프로그래밍 모델로 원활하게 마이그레이션하는 데 도움이됩니다.
React 철학은 대신 명령 패턴을 기반으로합니다.
참고 문헌
답변
간단한 서비스를 작성하고 사용할 수 있습니다.
/** eventsService */
module.exports = {
callbacks: {},
/**
* @param {string} eventName
* @param {*} data
*/
triggerEvent(eventName, data = null) {
if (this.callbacks[eventName]) {
Object.keys(this.callbacks[eventName]).forEach((id) => {
this.callbacks[eventName][id](data);
});
}
},
/**
* @param {string} eventName name of event
* @param {string} id callback identifier
* @param {Function} callback
*/
listenEvent(eventName, id, callback) {
this.callbacks[eventName][id] = callback;
},
/**
* @param {string} eventName name of event
* @param {string} id callback identifier
*/
unlistenEvent(eventName, id) {
delete this.callbacks[eventName][id];
},
};
예 (트리거링과 동일)
import eventsService from '../../../../services/events';
export default class FooterMenu extends Component {
componentWillMount() {
eventsService
.listenEvent('cart', 'footer', this.cartUpdatedListener.bind(this));
}
componentWillUnmount() {
eventsService
.unlistenEvent('cart', 'footer');
}
cartUpdatedListener() {
console.log('cart updated');
}
}
답변
컨텍스트를 통해 전달 된 콜백을 통해 이벤트를 버블 링 할 수 있습니다. [CodePen]
import * as React from 'react';
const MyEventContext = React.createContext(() => {});
const MyEventBubbleContext = ({children, onMyEvent}) => {
const bubbleEvent = React.useContext(MyEventContext);
const handleMyEvent = React.useCallback((...args) => {
// stop propagation if handler returns false
if (onMyEvent(...args) !== false) {
// bubble the event
bubbleEvent(...args);
}
}, [onMyEvent]);
return (
<MyEventContext.Provider value={handleMyEvent}>
{children}
</MyEventContext.Provider>
);
};
const MyComponent = () => (
<MyEventBubbleContext onMyEvent={e => console.log('grandparent got event: ', e)}>
<MyEventBubbleContext onMyEvent={e => console.log('parent got event: ', e)}>
<MyEventContext.Consumer>
{onMyEvent => <button onClick={onMyEvent}>Click me</button>}
</MyEventContext.Consumer>
</MyEventBubbleContext>
</MyEventBubbleContext>
);
export default MyComponent;
답변
특히 부모에서 자식으로 구멍을 뚫는 것이 이미 번거 롭다면 매우 합리적이라고 생각한 또 다른 것이 있습니다. 그는 그것을 덜 단순한 의사 소통이라고 불렀습니다. 링크는 다음과 같습니다.
https://github.com/ryanflorence/react-training/blob/gh-pages/lessons/04-less-simple-communication.md
답변
가능한 해결책 은 ReactJs 앱에서 Observer 패턴에 절대적으로 의존 해야하는 경우 일반 이벤트를 가로 챌 수 있습니다. 예를 들어, <div>
삭제 <div>
로 표시된를 삭제 키로 인해 발생 시키려면 customEvent에 의해 호출되는 keydown 이벤트를 수신하도록 할 수 있습니다 . 본문에 keydown을 트랩하고 customEvent
선택한에 keydown 이벤트를 전달합니다 <div>
. 누군가에게 도움이되는 경우 공유합니다.
답변
클라이언트에 상태를 배포 한 후 저장소에 ‘파견’상태를 백업하는 중앙 저장소 [Redux]도 관찰자 패턴과 같습니다. 게시 / 구독을 수행하는 방법은 props / events 경로를 연결하는 명시적인 (취약한?) 오버 헤드로 인해 더 나빠질뿐입니다. 계층 구조를 해킹하기 위해 React는 악취가 나는 컨텍스트 (제공자 패턴) 또는 관찰 가능한 라이브러리를 제공합니다. 새로운 데코레이터 @observable을 소개하는 MobX 또는 새로운 템플릿 구문 “v-if”를 도입하는 Vue와 같습니다. 이벤트는 어쨌든 DOM 및 자바 스크립트 이벤트 루프가 작동하는 기본 방법입니다. 사탄 숭배자들이 그랬다고 생각합니다. Lol
답변
나는이 질문이 지금 꽤 오래되었다는 것을 알고 있지만이 답변은 여전히 누군가를 도울 수 있습니다. 선언적 사용자 지정 이벤트를 추가하는 React 용 JSX pragma를 작성했습니다 : jsx-native-events .
기본적으로 onEvent<EventName>
패턴을 사용하여 이벤트를 감시합니다.
<some-custom-element onEventSomeEvent={ callback }></some-custom-element>