如何将从PostgreSQL获取的内容渲染为React JSX而非字符串?
解决React渲染HTML字符串为普通文本的问题
问题分析
- React默认会转义所有字符串内容,直接渲染HTML字符串会被当作普通文本显示,无法解析为HTML元素。
- 父组件存在异步更新时机问题:
dispatch更新Redux Store是异步操作,finally块执行时article可能还未从Store中更新,导致setFile设置的是旧值。
解决方案
步骤1:修正父组件的数据更新逻辑
用useEffect监听article的变化,确保file能拿到最新内容,替代原finally块的逻辑:
const ArticleCnt = () => { const dispatch = useDispatch() const { article } = useSelector(s => s.articleContent); const [file, setFile] = useState(""); const location = useLocation(); // 发起请求获取文章数据 useEffect(() => { axios.get("http://localhost:2003/article", { params: { id: location.pathname.split("/")[1] } }) .then(({ data }) => { dispatch(setArticleContentTo(data)) }) .catch((err) => console.log("Error Occured Here: ", err.message)) }, [dispatch, location.pathname]); // 监听article变化,更新本地state useEffect(() => { if (article) { setFile(article); } }, [article]); const containerVariants = { hidden: { x: "100vw" }, visible: { x: 0, transition: { duration: .6 } }, exit: { x: '-100vw', transition: { duration: .6, delay: 2 } } } return ( <motion.div className="app-main" variants={containerVariants} exit="exit" initial="hidden" animate="visible"> <ArticlePanel /> <div className="app-container"> <ArticleHeader /> <ArticleThumbnail /> <ArticleInfo /> <div className="app-article-cnt"> <ArticleContent articleFile={file} /> <ArticleComment /> </div> </div> </motion.div> ); }
步骤2:子组件用dangerouslySetInnerHTML渲染HTML
React提供dangerouslySetInnerHTML属性解析HTML字符串,同时建议对内容做XSS过滤保障安全:
// 可选但推荐安装dompurify过滤恶意内容:npm install dompurify import DOMPurify from 'dompurify'; const ArticleContent = ({ articleFile }) => { const [isPending, setIsPending] = useState(true); useEffect(() => { setIsPending(!articleFile); }, [articleFile]); // 清理HTML中的恶意脚本 const sanitizedContent = DOMPurify.sanitize(articleFile); return ( <div className="app-article-content"> {isPending ? ( <> <div> <h1><Skeleton /></h1> <Skeleton count={50} /> </div> </> ) : ( <div dangerouslySetInnerHTML={{ __html: sanitizedContent }} /> )} </div> ); }
注意事项
dangerouslySetInnerHTML的命名是为了提醒开发者:直接渲染未过滤的HTML存在XSS攻击风险,必须对用户提供的内容进行过滤。dompurify能有效清理HTML中的恶意脚本,大幅提升应用安全性。
内容的提问来源于stack exchange,提问作者Chinedu Fabian
相关产品推荐
相关产品推荐

