【问题标题】:draft.js - retrieve formatted text from dbDraft.js - 从数据库中检索格式化文本
【发布时间】:2020-11-14 14:42:54
【问题描述】:

我的 draft.js <TextEditor /> 使用文本填充 body,例如:'{"blocks":[{"key":"3mont","text":"lorem ipsum","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}],"entityMap":{}}' 并在使用 convertToRaw() 后将其持久化到数据库。

Post.js 中,我想从数据库中检索并显示格式化的text。 我已经读过,为了做到这一点,我必须使用convertToRaw(),然后在从数据库中检索它时使用convertFromRaw(),但我遇到了与this 相同的问题(我收到cors 错误和Unexpected token u in JSON at position 0) 每当我使用convertFromRaw() 并尝试从数据库中检索格式化的text 时。

我已将服务器设置为支持cors,那么为什么我会收到cors 错误?是因为我试图将无效响应解析为JSON? 如何从Post.js 的数据库中获取格式化的text? 任何帮助将不胜感激!

GitHub

CreatePost.js

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

  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,
        body: JSON.stringify(convertToRaw(this.state.body.getCurrentContent())),
      },
    })
      .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);
      });
  };

   // Attempt to map through blocks
   //getText = () => {
   // const {body} = this.state;
   //const arr = body.blocks.map(({ text }) => text).join(' ')
   // console.log(arr)
  //}

  render() {
    const { title, body } = this.state;

    return (
      <>
        <Navbar />
        <Tabs>
          <TabList>
            <Tab>Draft</Tab>
            <Tab>Preview</Tab>
          </TabList>
          <TabPanel>
            <div>
              <form onSubmit={this.submitHandler}>
                <div>
                // title input
                </div>
                <div>
                  <TextEditor
                    onChange={(value) => this.setState({ body: value })}
                    editorState={body}
                  />
                </div>
                <button type="submit">
                  Publish
                </button>
              </form>
            </div>
          </TabPanel>

          <TabPanel>
            <div>
              <h1>{title}</h1>
                // display body text value here too 
              {this.getText()}
            </div>
          </TabPanel>
        </Tabs>
      </>
    );
  }
}

Post.js(显示body文本)

  const [post, setPost] = useState({});
  const [error, setError] = useState(false);
  const id = props.match.params.id;

  const loadSinglePost = (slug, id) => {
    read(slug, id).then((data) => {
      if (error) {
        console.log(data.error);
        setError(data.error);
      } else {
        setPost(data)
        console.log(data);
      }
    });
  };

  useEffect(() => {
    const slug = props.match.params.slug;
    loadSinglePost(slug, id);
  }, [props]);

  return (
    <>
      <div>
        <h3>{post.title}</h3>
          ...
           // display text value below
          <p>{post.body}</p>
        </div>        
      </div>
    </>
  );
};

TextEditor.js

class TextEditor extends React.Component {
  constructor(props) {
    super(props);
    this.plugins = [addLinkPlugin];
  }
  toggleBlockType = (blockType) => {
    this.props.onChange(RichUtils.toggleBlockType(this.props.editorState, blockType));
  };
  handleKeyCommand = (command) => {
    const newState = RichUtils.handleKeyCommand(
      this.props.editorState,
      command
    );
    if (newState) {
      this.props.onChange(newState);
      return "handled";
    }
    return "not-handled";
  };

  onUnderlineClick = () => {
    this.props.onChange(
      RichUtils.toggleInlineStyle(this.props.editorState, "UNDERLINE")
    );
  };

  onBoldClick = (event) => {
    this.props.onChange(RichUtils.toggleInlineStyle(this.props.editorState, "BOLD"));
  };

  onItalicClick = () => {
    this.props.onChange(
      RichUtils.toggleInlineStyle(this.props.editorState, "ITALIC")
    );
  };

  onAddLink = () => {
    const editorState = this.props.editorState;
    const selection = editorState.getSelection();
    const link = window.prompt("Paste the link -");
    if (!link) {
      this.props.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.props.onChange(RichUtils.toggleLink(newEditorState, selection, entityKey));
  };

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

  render() {
    return (
      <div>
      // formatting buttons
        <div>
          <Editor
          blockStyleFn={getBlockStyle}
          editorState={this.props.editorState}
          handleKeyCommand={this.handleKeyCommand}
          onChange={this.props.onChange}
          plugins={this.plugins}
          placeholder="Post Content"
          />
        </div>
      </div>
    );
  }
}

【问题讨论】:

    标签: reactjs cors text-editor draftjs


    【解决方案1】:

    显然draft-js 没有 html 输出功能,因为它应该对输出没有任何假设,因此人们可以根据需要调整他们的输出 (see this)。这意味着我们必须自己实现它,如果您只是在寻找要保存在数据库中的 html 或 markdown 输出,那么 this mono repo 可以提供帮助。我已经在this sandbox 中实现了一个如何做到这一点的示例。请注意,我使用dangerouslySetInnerHTML 进行演示,这不是最佳的。您可能希望使用清理和富文本组件来显示帖子。事实上,如果可能的话,我建议放弃 html 并改用 markdown。

    【讨论】:

    • 感谢您的回答!它现在正在 CreatePost.js 的另一个选项卡上显示(格式化)。不过,我仍在努力让它在 Post.js 中显示。当我将onPublish 方法添加到CreatePost.js 中的按钮时,我得到this.props.onPublish is not a function,当我将其取出并保持按钮原样时,我得到与以前相同的输出。 @杰克逊
    • @Rahni 我的沙箱已经有Post.jsonPublish。当您单击发布按钮时,它只会显示Post.js 的实例。我认为您没有点击我沙箱中的发布按钮?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    相关资源
    最近更新 更多