在onClick处理程序

时间:2017-09-21 11:05:48

标签: javascript reactjs redux react-redux

我正在构建一个简单的模态组件,并尝试检测模态本身之外的点击。就目前而言,console.log内的handleClick正确输出一个布尔值。但是,取消注释props.openModal();会产生Cannot read property 'contains' of null。我知道我的逻辑/演示现在有点混乱;我只是在尝试学习React / Redux,并且只想了解为什么这种情况。提前致谢

ModalContainer.js

import { withRouter } from 'react-router';
import { connect } from 'react-redux';
import { Modal } from 'components';
import { bindActionCreators } from 'redux';
import * as actions from 'redux/modules/modal';

const mapStateToProps = function ({ modal }) {
  return {
    isOpen: modal.isOpen
  };
}

const mapDispatchToProps = function (dispatch) {
  return bindActionCreators({...actions}, dispatch);
}

export default withRouter(connect(
  mapStateToProps, mapDispatchToProps
)(Modal));

Modal.js

import React from 'react';
import PropTypes from 'prop-types';
import { a, b } from './modal.css';

function Modal(props) {
  let modalWindow = null;

  const setModalWindow = (node) => {
    modalWindow = node;
  }

  const onOpen = () => {
    // props.openModal();
    document.addEventListener('click', handleClick);
  }

  const onClose = () => {
    // props.closeModal();
    document.removeEventListener('click', handleClick);
  }

  const handleClick = (e) => {
    console.log(!modalWindow.contains(e.target));
  }

  return (
    <div>
      <span onClick={onOpen}>Open</span>
      <div className={a}>
        <div ref={setModalWindow} className={b}>
            <span onClick={onClose}>Close</span>
        </div>
      </div>
    </div>
  )
}

Modal.propTypes = {
  openModal: PropTypes.func.isRequired,
  isOpen: PropTypes.bool.isRequired,
  closeModal: PropTypes.func.isRequired
}

export default Modal;

动作/减速器:

// Modal Actions
const OPEN_MODAL = 'OPEN_MODAL';
const CLOSE_MODAL = 'CLOSE_MODAL';

export function openModal() {
  return {
    type: OPEN_MODAL
  }
}

export function closeModal() {
  return {
    type: CLOSE_MODAL
  }
}

//  Modal's reducer
const initialState = {
  text: '',
  isOpen: false
}

export default function modal(state = initialState, action) {
  switch (action.type) {
    case OPEN_MODAL:
      return {
        ...state,
        isOpen: true
      };
    case CLOSE_MODAL:
      return {
        text: '',
        isOpen: false
      };
    default:
      return state;
  }
}

1 个答案:

答案 0 :(得分:0)

  

当使用时,React将使用DOM元素调用ref回调   组件安装,并在卸载时调用它。

您必须使用“生命周期方法”以避免出现错误。

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { a, b } from './modal.css';

class Modal extends Component {
    constructor( props ) {
        super(props);

        this.modalWindow = null;
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick( e ) {
        console.log(!this.modalWindow.contains(e.target));
    }

    componentDidMount() {
        document.addEventListener('click', this.handleClick);
    }

    componentWillUnmount() {
        document.removeEventListener('click', this.handleClick);
    }

    render() {
        const { openModal, closeModal } = this.props;

        return (
            <div>
                <span onClick={openModal}>Open</span>
                <div className={a}>
                    <div ref={node => this.modalWindow = node} className={b}>
                        <span onClick={closeModal}>Close</span>
                    </div>
                </div>
            </div>
        );
    }
}

Modal.propTypes = {
    openModal: PropTypes.func.isRequired,
    isOpen: PropTypes.bool.isRequired,
    closeModal: PropTypes.func.isRequired
};

export default Modal;

您也可以使用this package作为您尝试解决的问题的一般解决方案。