我有一个更高阶的组件,它设置了一些值,然后将它们作为props传递给wrappedComponent,但是当我从componentDidMount()访问“this.props”时,在该包装组件中,值为空。如果我从wrappedComponent中的render方法放置日志“this.props”但是我得到了所需的结果,尽管我认为这是因为重新渲染。我在这做错了什么?
Home.js
import React, { Component } from 'react'
// eslint-disable-next-line
import { BrowserRouter as Router } from 'react-router-dom'
import { Route, Switch } from 'react-router-dom'
import BlogSummaryContainer from './utility/BlogSummaryContainer'
import BlogPost from './utility/BlogPost'
import EditableBlogPost from './utility/EditableBlogPost'
function withBlogPostData (WrappedComponent) {
return class BlogPostContainer extends React.Component {
constructor () {
super()
this.state = { title: '', content: '', catchPhrase: '' }
}
componentDidMount () {
fetch(`/api/posts/${this.props.match.params.id}`)
.then(res => {
return res.json()
})
.then(blogPost => {
// this setState doesnt reach the wrappedComponent in time even if i dont do a fetch and simply hard code a value, whats going on?
this.setState({
title: blogPost.title,
content: blogPost.content,
catchPhrase: blogPost.catchPhrase
})
})
}
render () {
return (
<WrappedComponent
id={this.props.match.params.id}
title={this.state.title}
content={this.state.content}
catchPhrase={this.state.catchPhrase}
/>
)
}
}
}
class Home extends Component {
... other code
render () {
return (
<Switch>
<Route
exact
path={`${this.props.match.url}`}
render={() => {
return <BlogSummaryContainer posts={this.state.blogPosts} />
}}
/>
<Route
exact
path={`${this.props.match.url}/:id`}
component={withBlogPostData(BlogPost)}
/>
<Route
exact
path={`${this.props.match.url}/:id/edit`}
component={withBlogPostData(EditableBlogPost)}
/>
<Route
exact
path={`${this.props.match.url}/new/post`}
render={() => {
return <EditableBlogPost isNew />
}}
/>
</Switch>
)
}
}
export default Home
EditableBlogPost.js
componentDidMount (props) {
const { title, catchPhrase, content } = this.props
console.log('this.props', this.props) // this.props = {title: "", content: "", ... }
}
答案 0 :(得分:1)
我认为这只是一个异步问题 - 当你的HOC挂载时,它正在调用fetch()
,而这个问题没有立即解决,所以这就是为什么第一个渲染this.state.x
是它们的初始空值。< / p>
解决Promise后,会设置值,后续render
将具有预期值。
在fetch()
已解决之前,您可以有条件地渲染以避免渲染包装的组件:
render () {
if(this.state.title.length === 0) {
return <div>Loading...</div>; //or some nice <Loading> component
}
return (
<WrappedComponent
id={this.props.match.params.id}
title={this.state.title}
content={this.state.content}
catchPhrase={this.state.catchPhrase}
/>
)
}