Draft.js - 从数据库中检索格式化文本

Rah*_*hni 5 text-editor cors reactjs draftjs

我的 Draft.js<TextEditor />填充body了文本 eg:'{"blocks":[{"key":"3mont","text":"lorem ipsum","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}],"entityMap":{}}'并在使用convertToRaw().

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

我已将服务器设置为支持cors,为什么会收到cors错误消息?是因为我试图将无效响应解析为JSON吗?如何text从 db 中获取格式Post.js?任何帮助将非常感激!

GitHub

创建Post.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>
      </>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

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>
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

文本编辑器.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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Jac*_*son 2

显然draft-js没有 html 输出功能,因为它应该对输出没有假设,因此人们可以根据需要调整其输出(请参阅此)。这意味着我们必须自己实现它,如果您只是寻找 html 或 markdown 输出来保存在数据库中,那么这个mono 存储库可能会有所帮助。我已经实现了一个如何在此沙箱中执行此操作的示例。请注意,我用于dangerouslySetInnerHTML演示的不是最佳的。您可能需要使用清理和富文本组件来显示帖子。事实上,如果可能的话,我建议放弃 html 并使用 markdown。