如何使用按钮的 onClick 将 AceEditor 的值传递给组件状态?响应式JS

How to pass the value of AceEditor to the component state using the onClick of a button? ReactJS

我目前正尝试在 ACE 编辑器的帮助下实现某种 CodeMirror。我试过将状态与 'onClick' 按钮参数一起使用,但实际上无法正常工作。

import React, { Component } from 'react';
import { makeStyles, createStyles } from '@material-ui/core/styles';
import './CodeMirror.css';
import { Box, Button } from '@material-ui/core';
// Import Brace and the AceEditor Component
import AceEditor from 'react-ace';
import TryItButton from '../CustomButton/TryItButton';
// Import a Mode (language)
import 'ace-builds/src-noconflict/mode-javascript';
// Import a Theme (okadia, github, xcode etc)
import 'ace-builds/src-noconflict/theme-twilight';

export interface AppProps {
  headings: {
    key: number;
    name: string;
    pathname: string;
  }[];
  subheadings: {
    key: number;
    name: string;
    calls: string[];
  }[];
}

interface AppState {
  value: string;
}

function onChange(newValue: string) {
  console.log('CodeMirror value: ', newValue);
}

export default class CodeMirror extends Component<AppProps, AppState> {
  constructor(props: AppProps) {
    super(props);
    this.state = { value: '' };
  }

  render(): JSX.Element {
    return (
      <>
        <div className="main-container-codemirror">
          <div className="top-block-codemirror">
            <Box className="top-bar-text-codemirror">
              <i className="white">Example Call</i>
            </Box>
          </div>

          <div className="example-block-codemirror">
            <div className="textarea-example">
              <AceEditor
                // placeholder="Enter a call here..."
                mode="javascript"
                theme="twilight"
                name="ace-editor"
                fontSize={12}
                showPrintMargin
                wrapEnabled
                showGutter
                highlightActiveLine
                value={this.state.value}
                setOptions={{
                  enableBasicAutocompletion: true,
                  enableLiveAutocompletion: true,
                  enableSnippets: false,
                  showLineNumbers: true,
                  tabSize: 2,
                  useWorker: false,
                }}
                style={{
                  position: 'relative',
                  width: '100%',
                  height: '100%',
                }}
                onChange={onChange}
              />
            </div>

            <div className="spacer">
              <Button
                className="try-it-button"
                style={{
                  backgroundColor: '#533cf8',
                  color: 'white',
                  borderRadius: 0,
                  fontSize: 13,
                  fontWeight: 200,
                }}
              >
                Try it!
              </Button>
              <div className="spacer-text-div">
                auto-update 'fat', alphabetize payload, and make the example
                call below
              </div>
            </div>

            <div className="header-2">
              <i className="white">Example Response</i>
            </div>

            <div className="textarea-example">
              <textarea
                readOnly
                className="example-code"
                value="Response code"
              />
            </div>

            <div className="bottom-block-codemirror" />
          </div>
        </div>
      </>
    );
  }
}

到目前为止,这是我的代码,但我想要做的是在选择 'Try it' 时,将输入到 AceEditor 组件中的文本存储在组件状态中(见下文。如果输入的文本也显示在底部文本区域会很好,但是在状态中获得这个值足以让我继续这个项目的其余部分。

我目前正在控制台中使用 'onChange' 显示在 AceEditor 中输入的任何内容,但在该组件本身的各个部分之间传递此值时遇到问题。谢谢。

CodeMirror Component

试试这个方法,

import "./styles.css";

import React, { Component } from "react";
import { makeStyles, createStyles } from "@material-ui/core/styles";
// import './CodeMirror.css';
import { Box, Button } from "@material-ui/core";
// Import Brace and the AceEditor Component
import AceEditor from "react-ace";
import TryItButton from "../CustomButton/TryItButton";
// Import a Mode (language)
import "ace-builds/src-noconflict/mode-javascript";
// Import a Theme (okadia, github, xcode etc)
import "ace-builds/src-noconflict/theme-twilight";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <CodeMirror />
      dsdsd
    </div>
  );
}

export interface AppProps {
  headings?: {
    key: number;
    name: string;
    pathname: string;
  }[];
  subheadings?: {
    key: number;
    name: string;
    calls: string[];
  }[];
}

interface AppState {
  value: string;
  textAreaValue?: string;
}

class CodeMirror extends Component<AppProps, AppState> {
  constructor(props: AppProps) {
    super(props);
    this.state = { value: "", textAreaValue: "" };
  }

  onChange(newValue: string) {
    console.log("CodeMirror value: ", newValue);
    this.setState({ value: newValue });
  }

  render() {
    return (
      <>
        <div className="main-container-codemirror">
          <div className="top-block-codemirror">
            <Box className="top-bar-text-codemirror">
              <i className="white">Example Call</i>
            </Box>
          </div>

          <div className="example-block-codemirror">
            <div className="textarea-example">
              <AceEditor
                // placeholder="Enter a call here..."
                mode="javascript"
                theme="twilight"
                name="ace-editor"
                fontSize={12}
                showPrintMargin
                wrapEnabled
                showGutter
                highlightActiveLine
                value={this.state.value}
                setOptions={{
                  enableBasicAutocompletion: true,
                  enableLiveAutocompletion: true,
                  enableSnippets: false,
                  showLineNumbers: true,
                  tabSize: 2,
                  useWorker: false
                }}
                style={{
                  // position: 'relative',
                  width: "100%",
                  height: "200px"
                }}
                onChange={(e) => this.onChange(e)}
              />
            </div>

            <div className="spacer">
              <Button
                className="try-it-button"
                onClick={() =>
                  this.setState((prev) => ({
                    ...prev,
                    textAreaValue: prev["value"]
                  }))
                }
                style={{
                  backgroundColor: "#533cf8",
                  color: "white",
                  borderRadius: 0,
                  fontSize: 13,
                  fontWeight: 200
                }}
              >
                Try it!
              </Button>
              <div className="spacer-text-div">
                auto-update 'fat', alphabetize payload, and make the example
                call below
              </div>
            </div>

            <div className="header-2">
              <i className="white">Example Response</i>
            </div>

            <div className="textarea-example">
              <textarea
                readOnly
                className="example-code"
                value={this.state.textAreaValue || "Response code"}
              />
            </div>

            <div className="bottom-block-codemirror" />
          </div>
        </div>
      </>
    );
  }
}

codeSandbox - https://codesandbox.io/s/reverent-microservice-yp2ff?file=/src/App.tsx:0-3764