0

我正在使用我的 react typescript 项目进行 Ant 设计,

这是我的冲突,我想点击标签并将其显示到Sun 编辑器内容区域,所以当我点击标签时会显示文本区域,但我无法在 sun 编辑器上添加任何解决方案?谢谢

闪电战在这里

代码在这里

import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Comment, Avatar, Form, Button, List, Input,Tag } from 'antd';
import moment from 'moment';
import 'suneditor/dist/css/suneditor.min.css';
import SunEditor from "suneditor-react";
const { TextArea } = Input;

const CommentList = ({ comments }) => (
  <List
    dataSource={comments}
    header={`${comments.length} ${comments.length > 1 ? 'replies' : 'reply'}`}
    itemLayout="horizontal"
    renderItem={props => <Comment {...props} />}
  />
);

const Editor = ({ onChange, onSubmit, submitting, value }) => (
  <>
    <Form.Item>
      <TextArea rows={4} onChange={onChange} value={value} />
    </Form.Item>
    <Form.Item>
      <Button htmlType="submit" loading={submitting} onClick={onSubmit} type="primary">
        Add Comment
      </Button>
    </Form.Item>
  </>
);

class App extends React.Component {
  state = {
    comments: [],
    submitting: false,
    value: '',
  };

  handleSubmit = () => {
    if (!this.state.value) {
      return;
    }

    this.setState({
      submitting: true,
    });

    setTimeout(() => {
      this.setState({
        submitting: false,
        value: '',
        comments: [
          ...this.state.comments,
          {
            author: 'Han Solo',
            avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
            content: <p>{this.state.value}</p>,
            datetime: moment().fromNow(),
          },
        ],
      });
    }, 1000);
  };

  handleChange = e => {
    this.setState({
      value: e.target.value,
    });
  };

  addTag = e => {
    const txt = e.target.innerHTML;
    this.setState(prevState => ({
      ...prevState,
      value: `${prevState.value} <${txt}> `,
    }));
  }

  render() {
    const { comments, submitting, value } = this.state;

    return (
      <>

       <div>
      <Tag onClick={this.addTag} color="magenta">First Name</Tag>
      <Tag onClick={this.addTag} color="red">Last Name</Tag>
      <Tag onClick={this.addTag} color="volcano">NIC</Tag>
      <Tag onClick={this.addTag} color="orange">FAX</Tag>
    
    </div>
        {comments.length > 0 && <CommentList comments={comments} />}
        <Comment
          avatar={
            <Avatar
              src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
              alt="Han Solo"
            />
          }
          content={
            <Editor
              onChange={this.handleChange}
              onSubmit={this.handleSubmit}
              submitting={submitting}
              value={value}
            />
          }
        />

        <SunEditor

                                                        autoFocus={true}
                                                        width="100%"
                                                        height="150px"
                                                        onChange={this.handleChange}
                                                        onClick={this.onSubmit}
                                           /*       defaultValue={value}*/
                                                        setOptions={{
                                                            buttonList: [
                                                                // default
                                                                ['undo', 'redo'],
                                                                ['bold', 'underline', 'italic', 'list'],
                                                                ['table', 'link', 'image'],
                                                                ['fullScreen'],
                                                                ['codeView']
                                                            ]

                                                        }}
                                                    

                                                        setContents={value}
                                                    />

      </>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));


  [1]: https://www.npmjs.com/package/suneditor-react
  [2]: https://stackblitz.com/edit/react-pqp2iu-ynivmu?file=index.js
4

1 回答 1

1

2021 年 5 月 13 日更新

handleChange()在 sun 编辑器中使用 state 会触发和之间的竞争问题addTag(),该状态有可能被旧状态替换。

要摆脱它,请使用 sun 编辑器参考来操作内容。

为了添加新文本并将其水平放置而不是垂直放置,它们具有一个insertHTML()功能,该功能将尊重 html 内容而无需<p>首先添加新内容。

更新代码: https ://stackblitz.com/edit/react-pqp2iu-axacak?file=index.js

  • 创建 editorRef
constructor() {
  super();
  this.editorRef = React.createRef();
}
  • 将 ref 应用到 sun 编辑器
<SunEditor ref={this.editorRef} ... />
  • 删除handleChange(),交给sun editor自己处理
  • 通过使用附加文本insertHTML()
addTag = e => {
    const txt = e.target.innerHTML;
    this.editorRef.current.editor.insertHTML(`{${txt}}`);
};

旧内容

<并且>在 sun 文本编辑器中具有特殊含义,它代表诸如<p> <a>etc 之类的 html 标签,它将在编辑器中隐藏。

因此,当您向<Firtname>编辑器申请时,它会消失。为了能够显示它,我建议您使用{}SendGrid 使用的 mustache 语法,Twilio 模板也是如此。

除此之外,handleChange在 sun 文本编辑器中将直接返回内容,因此无需从事件目标中获取它。

这是你的带有小胡子模板的分叉版本

https://stackblitz.com/edit/react-pqp2iu-axacak?file=index.js

handleChange = content => {
    console.log(content);
    this.setState({
      value: content
    });
};

addTag = e => {
    const txt = e.target.innerHTML;
    console.log(txt);
    this.setState(prevState => ({
      ...prevState,
      value: prevState.value.replace(/<\/p>$/, '') + `{${txt}}</p>` // remove the last </p>, append the new content, add back the </p> to avoid new line
    }));
};
于 2021-05-12T14:37:53.380 回答