this.props使用高阶组件在componentDidUpdate()中过期

时间:2018-04-01 23:40:34

标签: javascript reactjs ecmascript-6 react-router

我有一个更高阶的组件,它设置了一些值,然后将它们作为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: "", ... }
  }

1 个答案:

答案 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}
    />
  )
}