ReactJS - 在子事件处理程序中处理父事件
ReactJS - Handle parent event in child event handler
我有一个 React 容器,我想在其中捕获 mousemove
事件。这很简单。此外,我还有一个由容器呈现的反应子组件,其中实际上包含 mousemove
事件处理程序的逻辑。所以我需要 pass/delegate 从父容器到子容器的 mousemove
事件,并调用子容器的 mousemove
处理程序。如何正确完成?
我需要在容器而不是子组件中捕获鼠标事件,因为容器是 DOM 中较大的 HTML 元素,我需要在整个区域中捕获事件.
mousemove-handler-logic 需要在子组件中,因为它封装了一些容器不应该知道的功能。
容器的渲染方法:
render() {
return (
<div data-component="MyContainer"
onMouseMove={(event) => this.handleMousemove(event)}>
<MySubComponent {// ... give some props here}>
</div>
);
}
我尝试了一种方法,其中 MyContainer
为 MySubComponent
设置回调函数以检索其 DOM 节点并向 addEventListener
注册处理程序,但这种方法偶尔无法始终如一地工作DOM 节点未定义:
export default class MyContainer extends Component {
constructor(props) {
super(props);
this.state = {};
this.getContainerRef = this.getContainerRef.bind(this);
}
getContainerRef() {
return this.refs['containerWrap'];
}
render() {
return (
<div data-component="MyContainer"
ref="containerWrap"
onMouseMove={(event) => this.handleMousemove(event)}>
<MySubComponent getContainerRef={this.getContainerRef} />
</div>
);
}
}
export default class MySubComponent extends Component {
constructor(props) {
// ... init something
this.handleMousemove = this.handleMousemove.bind(this);
}
componentDidMount() {
// add event listener for parent application frame
let containerDOM = this.props.getContainerRef();
containerDOM.addEventListener('mousemove', this.handleMousemove, false);
}
componentWillUnmount() {
// remove event listener from parent application frame
let containerDOM= this.props.getContainerRef();
containerDOM.removeEventListener('mousemove', this.handleMousemove, false);
}
handleMousemove(event) {
// handle the event
}
// ... more methods
}
我还尝试通过 this.refs.SubComponent.handleMousemove
直接从 MyContainer
调用 MySubComponent
中的 mousemove
事件处理程序,但这在 react-redux 中被认为是不好的做法。
虽然你的 mousemove 应该在子组件中并且你的容器应该使用 mapDispatchtoProps,像这样
const mapDispatchToProps = (dispatch) => {
return {
onmousemoveAction: (id) => {
dispatch(toggleTodo(id))
}
}
}
并且在你的子组件 dispatch(onmousemoveAction)
但是如果您仍然希望在子组件中有逻辑,请执行
this.refs.mysubcomponent.dispatchEvent(new Event('mousedown'))
尽可能避免使用 refs
。
如果你想在父容器中捕获 onMouseMove
我认为最好的方法是将 event
的相关属性传递给你的子组件。当父组件 componentWillReceiveProps
和子组件中的 shouldComponentUpdate
的值发生变化时,您可以对其做出反应。
class Container extends React.Component{
constructor(props) {
super(props);
this.state = {
mouseX: 0,
mouseY: 0
};
}
handleMouse(event) {
event.preventDefault();
this.setState({
mouseX: event.clientX,
mouseY: event.clientY
});
}
render() {
return <div onMouseMove={(event) => this.handleMouse(event)} className="demo">
<Child x={this.state.mouseX} y={this.state.mouseY} />
</div>;
}
}
你的子组件:
class Child extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return this.handleMouseMove(nextProps.x, nextProps.y);
}
handleMouseMove(x, y) {
if (x < 150) { // return true to invoke render for some conditions
// your code
return true;
}
return false;
}
render() {
return <div>Child Component</div>;
}
}
但是您在子组件中的实现看起来像。它只需要了解其 props
而无需了解其父组件。
反应组件生命周期:https://facebook.github.io/react/docs/component-specs.html
我有一个 React 容器,我想在其中捕获 mousemove
事件。这很简单。此外,我还有一个由容器呈现的反应子组件,其中实际上包含 mousemove
事件处理程序的逻辑。所以我需要 pass/delegate 从父容器到子容器的 mousemove
事件,并调用子容器的 mousemove
处理程序。如何正确完成?
我需要在容器而不是子组件中捕获鼠标事件,因为容器是 DOM 中较大的 HTML 元素,我需要在整个区域中捕获事件.
mousemove-handler-logic 需要在子组件中,因为它封装了一些容器不应该知道的功能。
容器的渲染方法:
render() {
return (
<div data-component="MyContainer"
onMouseMove={(event) => this.handleMousemove(event)}>
<MySubComponent {// ... give some props here}>
</div>
);
}
我尝试了一种方法,其中 MyContainer
为 MySubComponent
设置回调函数以检索其 DOM 节点并向 addEventListener
注册处理程序,但这种方法偶尔无法始终如一地工作DOM 节点未定义:
export default class MyContainer extends Component {
constructor(props) {
super(props);
this.state = {};
this.getContainerRef = this.getContainerRef.bind(this);
}
getContainerRef() {
return this.refs['containerWrap'];
}
render() {
return (
<div data-component="MyContainer"
ref="containerWrap"
onMouseMove={(event) => this.handleMousemove(event)}>
<MySubComponent getContainerRef={this.getContainerRef} />
</div>
);
}
}
export default class MySubComponent extends Component {
constructor(props) {
// ... init something
this.handleMousemove = this.handleMousemove.bind(this);
}
componentDidMount() {
// add event listener for parent application frame
let containerDOM = this.props.getContainerRef();
containerDOM.addEventListener('mousemove', this.handleMousemove, false);
}
componentWillUnmount() {
// remove event listener from parent application frame
let containerDOM= this.props.getContainerRef();
containerDOM.removeEventListener('mousemove', this.handleMousemove, false);
}
handleMousemove(event) {
// handle the event
}
// ... more methods
}
我还尝试通过 this.refs.SubComponent.handleMousemove
直接从 MyContainer
调用 MySubComponent
中的 mousemove
事件处理程序,但这在 react-redux 中被认为是不好的做法。
虽然你的 mousemove 应该在子组件中并且你的容器应该使用 mapDispatchtoProps,像这样
const mapDispatchToProps = (dispatch) => {
return {
onmousemoveAction: (id) => {
dispatch(toggleTodo(id))
}
}
}
并且在你的子组件 dispatch(onmousemoveAction)
但是如果您仍然希望在子组件中有逻辑,请执行
this.refs.mysubcomponent.dispatchEvent(new Event('mousedown'))
尽可能避免使用 refs
。
如果你想在父容器中捕获 onMouseMove
我认为最好的方法是将 event
的相关属性传递给你的子组件。当父组件 componentWillReceiveProps
和子组件中的 shouldComponentUpdate
的值发生变化时,您可以对其做出反应。
class Container extends React.Component{
constructor(props) {
super(props);
this.state = {
mouseX: 0,
mouseY: 0
};
}
handleMouse(event) {
event.preventDefault();
this.setState({
mouseX: event.clientX,
mouseY: event.clientY
});
}
render() {
return <div onMouseMove={(event) => this.handleMouse(event)} className="demo">
<Child x={this.state.mouseX} y={this.state.mouseY} />
</div>;
}
}
你的子组件:
class Child extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return this.handleMouseMove(nextProps.x, nextProps.y);
}
handleMouseMove(x, y) {
if (x < 150) { // return true to invoke render for some conditions
// your code
return true;
}
return false;
}
render() {
return <div>Child Component</div>;
}
}
但是您在子组件中的实现看起来像。它只需要了解其 props
而无需了解其父组件。
反应组件生命周期:https://facebook.github.io/react/docs/component-specs.html