我使用React和Redux构建一个小型博客应用。 博客显示帖子页面的标题,作者,标签和帖子的描述。点击标题或"阅读更多"按钮,我想从本地项目的所有帖子的数据文件夹中加载和呈现带有相应帖子的HTML文件。
Redux正在管理博客的状态,加载包含8个不同帖子的初始posts.json文件,包括数据文件夹中相应html文件的htmlPath。
答案 0 :(得分:18)
我看到的方式是你要解决2个问题。第一个是如何在React中设置元素的innerHTML
。另一种是如何根据给定的变量(例如当前路线,文本字段的输入等)来获取要呈现的特定HTML。
innerHTML
您可以使用dangerouslySetInnerHTML
道具执行此操作。顾名思义,它将所述元素的innerHTML
设置为您指定的任何内容......是的,"危险地"是准确的,因为它打算让你在使用此功能前三思而后行。
不正确地使用innerHTML可能会导致跨站点脚本(XSS)攻击。清理用户输入以进行显示非常容易出错,无法正确清理是导致网络漏洞的主要原因之一。
查看此Demo或下面的代码段。
var Demo = React.createClass({
getInitialState: function() {
return {showExternalHTML: false};
},
render: function() {
return (
<div>
<button onClick={this.toggleExternalHTML}>Toggle Html</button>
{this.state.showExternalHTML ? <div>
<div dangerouslySetInnerHTML={this.createMarkup()} ></div>
</div> : null}
</div>
);
},
toggleExternalHTML: function() {
this.setState({showExternalHTML: !this.state.showExternalHTML});
},
createMarkup: function() {
return {__html: '<div class="ext">Hello!</div>'};
}
});
ReactDOM.render(
<Demo />,
document.getElementById('container')
);
&#13;
.ext {
margin-top: 20px;
width: 100%;
height: 100px;
background: green;
color: white;
font-size: 40px;
text-align: center;
line-height: 100px;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
&#13;
请注意,上面的示例实际上并不从外部文件获取HTML,而是直接以字符串形式输入。
动态获取选择特定文件的一种简单方法是让后端(例如php)从本地文件夹中读取文件,解析文本,然后通过AJAX请求将其发回。
//Your React component
fetchExternalHTML: function(fileName) {
Ajax.getJSON('/myAPI/getExternalHTML/' + fileName).then(
response => {
this.setState({
extHTML: response
});
}, err => {
//handle your error here
}
);
}
答案 1 :(得分:7)
虽然克里斯的答案很好,但还需要进行一些挖掘才能使其发挥作用。以下是您需要采取的步骤:
将html加载器添加到您的项目中:
npm i -D html-loader
将以下规则添加到webpack.config文件中:
{
test: /\.(html)$/,
use: {
loader: 'html-loader',
options: {
attrs: [':data-src']
}
}
}
现在您可以按如下方式导入html文件:
import React, { Component } from 'react';
import Page from './test.html';
var htmlDoc = {__html: Page};
export default class Doc extends Component {
constructor(props){
super(props);
}
render(){
return (<div dangerouslySetInnerHTML={htmlDoc} />)
}}
答案 2 :(得分:0)
您可以尝试react-templates。这是''最好的。您可以将模板作为外部文件,并可以随时加载,并且可以使用所有可用的React API进行渲染。
希望它有所帮助。
答案 3 :(得分:-1)
如果您确定,请将帖子内容从服务器代码的文件系统前端开始,并使用dangerouslySetInnerHTML
在React组件中显示:
function createMarkup() {
return {__html: 'First · Second'};
};
<div dangerouslySetInnerHTML={createMarkup()} />
更多文档:https://facebook.github.io/react/tips/dangerously-set-inner-html.html