onBlur / onClick与React中的CodeMirror2冲突

时间:2019-11-16 12:13:52

标签: javascript reactjs onclick codemirror onblur

我创建了多个CodeMirror单元。 OnBlur可以正常工作,但是,如果我在另一个单元格上单击run按钮,而不是触发运行,它实际上会触发onBlur,然后我需要再次单击鼠标来触发运行。理想情况下,当单击运行按钮时,应同时触发这两个事件。

我已经看到问题在于这两个事件的优先级,建议的解决方案之一是像这样ref那样向代码镜像添加ref = {cell => this.cell = cell}属性,然后在另一个处理程序中与运行按钮相关的操作this.cell.focus()或以类似​​的方式进行。

不幸的是,我什至无法访问CodeMirror2的ref属性,所以我无法对其进行测试。我将粘贴这两个组件,任何建议都会受到赞赏。

总结:问题是onBlur遮盖了onClick,因此需要单击运行按钮两次。我希望能够单击“运行”按钮,同时onBlurhandleRunClick均会触发。

import React, { Component } from "react";
import { Controlled as CodeMirror } from "react-codemirror2";
import CellResults from "./CellResults";
import CellToolbar from "../Shared/CellToolbar";
import AddCellButton from "../Shared/AddCellButton";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/darcula.css";
import "codemirror/mode/javascript/javascript.js";
import "codemirror/mode/ruby/ruby.js";
import "codemirror/mode/python/python.js";

class CodeCell extends Component {
  state = {
    code: this.props.cell.code
  };

  handleChange = value => {
    this.setState({ code: value });
  };

  handleBlur = () => {
    this.props.onUpdateCodeState(this.state.code, this.props.cellIndex);

    if (this.props.language === "Markdown") {
      this.props.toggleRender(this.props.cellIndex);
    }
  };

  render() {
    const cell = this.props.cell;
    const cellOptions = {
      mode: cell.type.toLowerCase(),
      theme: "darcula",
      lineNumbers: true,
      showCursorWhenSelecting: true
    };

    return (
      <div>
        <div className="add-cell-container">
          <AddCellButton
            className="add-cell-btn"
            onClick={this.props.onAddClick}
            cellIndex={this.props.cellIndex}
          />
        </div>
        <CellToolbar
          cellIndex={this.props.cellIndex}
          onDeleteClick={this.props.onDeleteClick}
          language={cell.type}
          onLanguageChange={this.props.onLanguageChange}
          rendered={cell.rendered}
          onRunClick={this.props.onRunClick}
        />
        <CodeMirror
          value={this.state.code}
          options={cellOptions}
          onBeforeChange={(editor, data, value) => {
            this.handleChange(value);
          }}
          onBlur={this.handleBlur}
        />
        {cell.type !== "Markdown" ? (
          <CellResults language={cell.type} results={cell.results} />
        ) : null}
      </div>
    );
  }
}

export default CodeCell;
import React from "react";
import Button from "react-bootstrap/Button";

class RunCellButton extends React.Component {
  handleRunClick = () => {
    this.props.onClick(this.props.cellIndex);
  };
  render () {
    return (
      <Button
        className="run-button"
        onClick={this.handleRunClick}
        variant="secondary"
        size="sm"
      >
        <span>&#9658;</span>
      </Button>
    );
  }



};

export default RunCellButton;

以下是“添加单元格”的类似问题。当我触发click事件触发时,show的状态将更改为true,但是如果我在行36上登录它,则它仍然是false。再次由于这个obBlue遮盖了其他所有内容,因此又触发了来自其他组件的click事件,因此每个按钮都需要单击两次。

import React, { Component } from "react";
import SplitButton from "react-bootstrap/SplitButton";
import * as constants from "../../Constants/constants";
import DropdownButton from "react-bootstrap/DropdownButton";
import Dropdown from "react-bootstrap/Dropdown";

class AddCellButton extends Component {
  state = {
    show: false
  }
  handleSelectCellType = language => {
    this.props.onClick(this.props.cellIndex, language);
  };

  handleToggle = () => {
    this.setState((prevState) => {
      return {
        show: !prevState["show"]
      }
    })
  }

  render() {
    const dropDownItems = constants.LANGUAGES.map(language => {
      return (
        <Dropdown.Item
          as="button"
          value={language}
          key={language}
          eventKey={language}
        >
          {language}
        </Dropdown.Item>
      );
    });
    console.log("state of show " + this.state.show)
    return (
      <DropdownButton
        show={this.state.show}
        onToggle={this.handleToggle}
        className="add-cell-btn"
        variant="secondary"
        id="dropdown-basic-button"
        title={<span>&#43;</span>}
        size="sm"
        onSelect={this.handleSelectCellType}
      >
        {dropDownItems}
      </DropdownButton>
    );
  }
}

export default AddCellButton;

0 个答案:

没有答案