1

我正在使用marked.js 使用markdown 创建帖子。使用降价成功创建帖子并且html正在显示但是当我更新/编辑帖子时,sanitizedHtml它没有被更新,它仍然包含旧内容。

其他字段正在更新,但sanitizedHtml依赖于来自的值body,然后将其转换为html并在后端对其进行清理。

没有更新sanitizedHtml,因为我没有body在 React 中设置它,我该如何解决它并sanitizedHtml使用新值更新body

Post.js 模型

// ...
const marked = require("marked");
const createDomPurify = require("dompurify");
const { JSDOM } = require("jsdom");
const domPurify = createDomPurify(new JSDOM().window);

const postSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
  },
  body: {
    type: String,
    required: true,
  },
 // ...
  sanitizedHtml: {
    type: String,
    required: true,
  },
});

postSchema.pre("validate", function (next) {
  // markdown - sanitize and convert to html
  if (this.body) {
    this.sanitizedHtml = domPurify.sanitize(marked(this.body));
  }
  next();
});

EditPost.tsx

const EditPost = ({ match } : { match: any }) => {
  const [values, setValues] = useState({
    title: "",
    body: "",
    error: "",
    sanitizedHtml: "",
    updatedPost: "",
  });

  const [post, setPost] = useState({ title: values.title, body: values.body, sanitizedHtml: values.sanitizedHtml });
  const { token } = isAuthenticated();
  const { title, body, error, updatedPost, sanitizedHtml } = values;

  const init = (slug: string, id: number) => {
    read(slug, id).then((data) => {
      if (data.error) {
        setValues({ ...values, error: data.error });
      } else {
        setValues({ ...values, title: data.title, body: data.body, sanitizedHtml: data.sanitizedHtml });
        setPost({ title: values.title, body: values.body, sanitizedHtml: values.sanitizedHtml });
      }
    });
  };

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

  useEffect(() => {
    setPost({ ...values });
  }, [values.title, values.body, values.sanitizedHtml]);

  const handleChange = (name: string) => (event: any) => {
    setValues({ ...values, [name]: event.target.value });
  };

  const clickSubmit = (event: any) => {
    event.preventDefault();
    setValues({ ...values, error: "" });
    setPost({ title: values.title, body: values.body, sanitizedHtml: values.sanitizedHtml });

    editPost(match.params.userId, match.params.id, token, post).then((data) => {
      if (data.error) {
        setValues({ ...values, error: data.error });
      } else {
        setValues({
          ...values,
          title: data.title,
          body: data.body,
          sanitizedHtml: data.sanitizedHtml,
          updatedPost: data.title,
          error: "",
        });

        console.log(post);
        console.log(data);
      }
    });
  };

  const newPostForm = () => (
    <form onSubmit={clickSubmit}>
      <div>
        <input
          onChange={handleChange("title")}
          type="text"
          name="title"
          value={title}
        />
      </div>

      <div>
        <textarea
          onChange={handleChange("body")}
          value={body}
          name="body"
        />
      </div>

      <button type="submit">
        Publish
      </button>
    </form>
  );

  return (
    <>
    <div>
      {newPostForm()}
    </div>
    </>
  );
};

export default EditPost;

控制器/posts.js

exports.edit = (req, res) => {
  const id = req.params.id;
  if (!ObjectID.isValid(id))
    return res.status(400).send(`No post with given id: ${id}`);
  const { title, body, sanitizedHtml } = req.body;

  const updatedPost = { title, body, sanitizedHtml };
  Post.findByIdAndUpdate(
    id,
    {
      $set: updatedPost,
    },
    { new: true },
    (error, data) => {
      if (error) {
        return error;
      } else {
        res.send(data);
        console.log(updatedPost);
      }
    }
  );
};
4

1 回答 1

1

解决了!我也需要在前端使用marked.js。
我添加了以下代码将文本区域值转换为降价并将其设置为sanitizedHtml状态:

let marked = require("marked");
sanitizedHtml: marked(values.body)
于 2020-11-29T22:11:32.613 回答