Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript onBlur/onClick与React中的CodeMirror2冲突_Javascript_Reactjs_Onclick_Codemirror_Onblur - Fatal编程技术网

Javascript onBlur/onClick与React中的CodeMirror2冲突

Javascript onBlur/onClick与React中的CodeMirror2冲突,javascript,reactjs,onclick,codemirror,onblur,Javascript,Reactjs,Onclick,Codemirror,Onblur,我已经创建了多个代码镜像单元。OnBlur工作正常,但是如果我在另一个单元格上单击run按钮,而不是触发run,它实际上会触发OnBlur,然后我需要再次单击鼠标来触发run。理想情况下,这两个事件都应该在单击“运行”按钮时触发 我已经看到,问题在于这两个事件的优先顺序,建议的解决方案之一是向代码镜像添加ref属性,如ref={cell=>this.cell=cell},然后在与run按钮dothis.cell.focus()相关的另一个处理程序中添加 不幸的是,我甚至无法访问CodeMirro

我已经创建了多个代码镜像单元。OnBlur工作正常,但是如果我在另一个单元格上单击
run
按钮,而不是触发run,它实际上会触发OnBlur,然后我需要再次单击鼠标来触发run。理想情况下,这两个事件都应该在单击“运行”按钮时触发

我已经看到,问题在于这两个事件的优先顺序,建议的解决方案之一是向代码镜像添加
ref
属性,如
ref={cell=>this.cell=cell}
,然后在与run按钮do
this.cell.focus()
相关的另一个处理程序中添加

不幸的是,我甚至无法访问CodeMirror2的
ref
属性,因此无法测试它。我将粘贴这两个组件,任何建议都将不胜感激

总而言之:问题在于onBlur shadows onClick,所以运行按钮需要单击两次。我希望能够单击“运行”按钮,同时
onBlur
handleRunClick
fire

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;

与上面的问题相关,当我单击其他按钮时,我会遇到相同的问题,例如,当我想单击创建下拉列表以插入新单元格的按钮时。如果元素的类型是button,我尝试过使用
e.relatedTarget.dropdown()
,但这并没有起作用,因为它说
dropdown()
不是函数。Dropdown是使用bootstrap
DropdownButton
实现的。我无法将Dropdown button show属性的状态更改为
true
的原因之一可能是,当在
handleBlur
中调用
onUpdateCodeState
时,我试图在callback中设置状态,它说react不能在卸载的组件中执行状态更新。因此,
onUpdateCodeState
卸载组件,但不确定如何处理。
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;
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;