提问者:小点点

使用高阶组件this.props过时的组件


我有一个高阶组件,它设置一些值,然后将这些值作为道具传递给wrappedComponent,但是当我从componentDidMount()访问“this.props”时,在该wrappedComponent中的值为空。如果我将render方法中的日志“this.props”放在wrappedComponent中,我会得到所需的结果,尽管我假设这是因为重新渲染。我做错了什么?

家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

可编辑的博客。js

  componentDidMount (props) {
    const { title, catchPhrase, content } = this.props
    console.log('this.props', this.props) // this.props = {title: "", content: "", ... }
  }

共1个答案

匿名用户

我认为这只是一个异步问题-当您的HOC挂载时,它调用的是fetch(),这并没有立即得到解决,这就是为什么在第一次渲染时会出现这种情况。状态x是它们的初始空值。

解析promise后,将设置值,随后的渲染将具有预期值。

您可以有条件地渲染,以避免在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}
    />
  )
}