【问题标题】:this.props out of date inside componentDidUpdate() using Higher Order Componentthis.props 使用高阶组件在 componentDidUpdate() 中过期
【发布时间】:2018-09-11 05:19:00
【问题描述】:

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

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: "", ... }
  }

【问题讨论】:

    标签: javascript reactjs ecmascript-6 react-router


    【解决方案1】:

    我认为这只是一个异步问题 - 当您的 HOC 挂载时,它正在调用 fetch(),这不会立即解决,所以这就是为什么在第一次渲染时 this.state.x 是它们的初始空值。

    当 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}
        />
      )
    }
    

    【讨论】:

    • 不幸的是,情况并非如此,即使没有获取,简单地对值进行硬编码也不起作用。我按原样包含示例的唯一原因是因为否则我会被告知只在构造函数中进行变量设置。
    • 当您说您对值进行硬编码时,您是指在constructor() 还是在setState() 调用中?
    • componentDidMount () { this.setState({ title: 'hello world' }) } 这给出了与 fetch 相同的结果。即:标题:“”,内容:“”,流行语:“”}
    • setState() 也不会立即更新状态。尝试在constructor() 中设置this.state = {} 的值,我怀疑这可能有效
    • 我需要获取到后端。据我了解,这不是您在构造函数中所做的事情
    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 2017-07-20
    • 2020-03-08
    • 2019-05-16
    • 2018-12-31
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多