当前位置: 首页 > 知识库问答 >
问题:

草稿js:文本编辑器从其他组件的状态填充值

阎元徽
2023-03-14

我正在使用草稿。js制作一个文本编辑器,我有两个组件:CreatePost。js从后端获取post字段,并使用用户输入和文本编辑器填充状态。js包含一个文本编辑器,我正在CreatePost中使用它。js。文本编辑器应在CreatePost状态下填充正文字段。jsonChange。

我的问题是如何让文本编辑器填充其他组件中的状态?我需要使用道具吗?

之前,我在CreatePost.js中有一个文本区域,它填充了主体。我希望另一个组件中的文本编辑器来填充它。我尝试使用

posts.js(控制器)

exports.create = (req, res) => {
  const { title, body, date } = req.body;
  const post = new Post({
    title,
    body,
    date,
    "author.id": req.profile._id,
    "author.name": req.profile.name,
  });
  post
    .save()
    .then((response) => {
      res.send(response);
    })
    .catch((err) => {
      return res.status(400).json({
        error: errorHandler(err),
      });
    });
};

CreatePost。js

class CreatePost extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      title: "",
      body: "",
      createdPost: "",
      error: "",
    };
  }

  changeHandler = (e) => {
    this.setState({ [e.target.name]: e.target.value });
  };

  submitHandler = (e) => {
    e.preventDefault();
    const {
      user: { _id },
    } = isAuthenticated();
    axios({
      url: `${API}/post/new-post/${_id}`,
      method: "POST",
      data: this.state,
    })
      .then((response) => {
        this.setState({ createdPost: this.state.title });
        return response;
      })
      .catch((error) => {
        if (!this.state.title || !this.state.body) {
          this.setState({
            error: "This post must contain a title and a body.",
          });
        }
        console.log(error);
      });
  };

...

  render() {
    const { title, body } = this.state;
    return (
      <>
        <Navbar />
        <Tabs>
          <TabList className="tabs">
            <Tab className="tab">Draft</Tab>
            <Tab className="tab">Preview</Tab>
          </TabList>
          <TabPanel>
            <div className="newpost_container">
              <form className="newpost_form" onSubmit={this.submitHandler}>
                <div className="form-group">
                  <input
                    type="text"
                    placeholder="Title"
                    name="title"
                    className="newpost_field newpost_title"
                    onChange={this.changeHandler}
                    value={title}
                  />
                </div>
                <div className="form-group newpost_body">
                <TextEditor />
                </div>
                <button className="btn publish-post-btn" type="submit">
                  Publish
                </button>
                {this.showSuccess()}
                {this.showError()}
              </form>
            </div>
          </TabPanel>

          <TabPanel>
            <div>
              <h1>{title}</h1>
              <div>{body}</div>
            </div>
          </TabPanel>
        </Tabs>
      </>
    );
  }
}

export default CreatePost;

文本编辑器。js

class TextEditor extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      editorState: EditorState.createEmpty(),
    };
    this.plugins = [addLinkPlugin];
  }
  toggleBlockType = (blockType) => {
    this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType));
  };

  onChange = (editorState) => {
    this.setState({
      editorState,
    });
  };

  handleKeyCommand = (command) => {
    const newState = RichUtils.handleKeyCommand(
      this.state.editorState,
      command
    );
    if (newState) {
      this.onChange(newState);
      return "handled";
    }
    return "not-handled";
  };

// onClick for format options

  onAddLink = () => {
    const editorState = this.state.editorState;
    const selection = editorState.getSelection();
    const link = window.prompt("Paste the link -");
    if (!link) {
      this.onChange(RichUtils.toggleLink(editorState, selection, null));
      return "handled";
    }
    const content = editorState.getCurrentContent();
    const contentWithEntity = content.createEntity("LINK", "MUTABLE", {
      url: link,
    });
    const newEditorState = EditorState.push(
      editorState,
      contentWithEntity,
      "create-entity"
    );
    const entityKey = contentWithEntity.getLastCreatedEntityKey();
    this.onChange(RichUtils.toggleLink(newEditorState, selection, entityKey));
  };

  toggleBlockType = (blockType) => {
    this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType));
  };

  render() {
    return (
      <div className="editorContainer">
        <div className="toolbar">
          <BlockStyleToolbar
            editorState={this.state.editorState}
            onToggle={this.toggleBlockType}
          />
          // format buttons
        </div>

        <div>
          <Editor
            placeholder="Post Content"
            blockStyleFn={getBlockStyle}
            editorState={this.state.editorState}
            handleKeyCommand={this.handleKeyCommand}
            onChange={this.onChange}
            plugins={this.plugins}
            placeholder="Post Content"
          />
        </div>
      </div>
    );
  }
}

export default TextEditor;

共有1个答案

慕铭
2023-03-14
匿名用户

看起来你已经非常接近解决这个问题了。当使用道具向下发送更改处理程序到TextEditor时,您走在了正确的道路上。解决问题的一个方法是向上移动editorState到你的CreatePost组件,然后向下传递值和更改处理程序。如果您这样做,您应该从TextEditor文件中删除editorState和更改处理程序。通过继续你的例子,这样的东西应该会起作用,我还没有尝试过代码,但是它应该会帮助你朝着正确的方向前进。

在CreatePost.js

constructor(props) {
    super(props);
    this.state = {
      title: "",
      body: EditorState.createEmpty(),
      createdPost: "",
      error: "",
    };
}

....

<TextEditor onChange={(value) => this.setState({ body: value })} editorState={body} />

文本ditor.js

<Editor
  placeholder="Post Content"
  blockStyleFn={getBlockStyle}
  editorState={this.props.editorState}
  handleKeyCommand={this.handleKeyCommand}
  onChange={this.props.onChange}
  plugins={this.plugins}
  placeholder="Post Content"
/>

当发布数据时,我们需要访问编辑器的内容,而不是EditorState。我们可以通过draft.jsAPI做到这一点(请参阅此处的更多内容:https://draftjs.org/docs/api-reference-editor-state/#getcurrentcontent)。不幸的是,这还不够。我们还需要将内容转换为更容易处理的格式。我们可以通过draft.jstranstToRaw来实现这一点,您还需要从库(https://draftjs.org/docs/api-reference-data-conversion/#converttoraw)导入。转换为原始返回一个JS对象,所以我们还需要将其转换为字符串,然后才能使用JSON. stringify()将其发送到服务器。

axios({
  url: `${API}/post/new-post/${_id}`,
  method: "POST",
  data: {
    ...this.state,
    body: JSON.stringify(convertToRaw(this.state.body.getCurrentContent()))
  }
})

 类似资料:
  • 问题内容: 我试图将的保存到数据库,然后再次读取并重新创建EditorContent对象。但是剥去富文本内容。我不知道该怎么办。 我如何正确坚持? 问题答案: 顾名思义,该方法仅返回纯文本,没有任何格式丰富的格式。您应该使用convertToRaw()和convertFromRaw()函数来序列化和反序列化编辑器的内容。 如有必要,可以通过以下方式导入它们:(假设您正在使用ES6) 如果您需要导出

  • Telegram机器人向我发送了一条带有文本片段的消息,我想对其进行编辑,并将其发送回机器人进行进一步处理。 复制和粘贴需要时间。重新键入消息需要时间。 理想情况下,我想按下机器人消息上的内联按钮“编辑”,并让消息文本出现在我的回复输入框中进行编辑。(以某种方式附加到我的回复的消息ID将是一个加号)。 我试着使用除/start*之外的参数的深度链接,但这似乎不起作用。 我可以使用机器人API(或任

  • 问题内容: 如何从文本文件填充? 问题答案: 非常模糊的问题。您是说要每行输入一个吗?如果是这样,则要使用BufferedReader之类的东西,请读取所有行,并将它们保存为String数组。创建一个新的JComboBox传入该String构造函数。

  • 问题内容: 我有下表,其中的表是空的,我正在尝试填充: 要填充的源数据是我从外部CSV文件填充的临时表: 我想做的是用中的值填充。该字段可以直接复制,但是我不太确定如何获取正确的内容(可以使用tmp_table.langname确定language.id)和(tmp_table.tplname,tmp_table.source,tmp_table.domain一起使用)确定template.id)

  • 我遇到了以下问题:当手机应该输入时,我需要实现这种情况的解决方案。这部手机应该有不可移动的部分,最后四个数字应该在开头填写下划线,然后当用户键入下划线时,应该将其更改为数字,例如: < code> 12345____ - 我实现了不可移除的部分。我是这样做的: 但现在我不明白,如何处理下划线的逻辑。我尝试在< code>doAfterTextChanged中添加下划线,比如if