我对React还是很陌生,我正试图延迟加载存储在服务器上的markdown文件。
我尝试设置一个异步箭头功能来获取文件并通过标记运行它。 我在https://codesandbox.io/s/7zx3jlrry1处找到了这个演示,我尝试了它,但还没有弄清楚如何遵循它。
class Markdown extends React.Component {
constructor(props) {
super(props)
this.state = {
// some state
}
}
render() {
let markdown = React.lazy(async () => {
// fetch the file
const response = await fetch(path)
if (!response.ok) {
return (<p>Response was not ok</p>)
} else {
// if successful, return markdown
let blob = await response.blob()
return marked(blob)
}
})
return (
<React.Suspense fallback={<div class="markdown">Loading</div>}>
<div class="markdown" id={this.props.id} dangerouslySetInnerHTML={{__html: markdown}} />
</React.Suspense>
)
}
}
当我尝试调试它时,箭头函数实际上并未执行,并且div的内部HTML是“ [object Object]”。 对于我如何实现这一目标的任何帮助,将不胜感激。
答案 0 :(得分:1)
您在HTML中得到[object Object]
,因为dangerouslySetInnerHTML需要一个返回对象{__html: '<div>some html string</div>'}
的函数。除此之外,您没有使用建议的通过网络请求获取数据的方式。请继续阅读以获取有关如何执行任务的更多详细信息。
React Suspense用于延迟加载Components
,而不是像react docs所声明的那样获取数据:
将来,我们计划让Suspense处理更多方案,例如数据提取。
React.Suspense可让您指定加载指示器,以防其下方树中的某些组件尚未准备好呈现。如今,延迟加载组件是唯一受支持的用例:
在这种情况下,您不需要延迟加载。使用react-lifecycle方法来执行诸如在正确时间获取数据之类的事情。您在这里需要的是react-lifecylce方法componentDidMount
。您也可以使用component state
来控制呈现的内容和未呈现的内容。例如,您可以通过设置变量来显示error occured
或loading
。
class Markdown extends React.Component {
constructor(props) {
super(props)
this.state = {
loading: true,
error: false,
html: ""
}
}
componentDidMount = () => {
this.fetchMarkdown()
}
fetchMarkdown = async () => {
const response = await fetch(path)
if (!response.ok) {
// if failed set loading to false and error to true
this.setState({ loading: false, error: true })
} else {
// If successful set the state html = markdown from response
let blob = await response.text()
this.setState({ loading: false, html: blob })
}
}
getMarkup = () => {
return { __html: this.state.html }
}
render() {
if (this.state.error) {
return <div>Error loading markup...</div>
}
else if (this.state.loading){
return <div>Loading...</div>
}
else {
return <div class="markdown" id={this.props.id} dangerouslySetInnerHTML={this.getMarkup()} />
}
}
}