This.props устарел внутри componentDidUpdate () с использованием компонента более высокого порядка

У меня есть компонент более высокого порядка, который устанавливает некоторые значения, а затем передает их как props в wrappedComponent, однако внутри этого завернутого компонента, когда я обращаюсь к this.props из componentDidMount (), значения остаются пустыми. Если я помещаю журналы "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.info('this.props', this.props) // this.props = {title: "", content: "", ... }
  }
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
217
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что это просто асинхронная проблема - когда ваш HOC монтируется, он вызывает fetch(), который не решается мгновенно, поэтому при первом рендеринге this.state.x являются их начальными пустыми значениями.

Когда обещание разрешено, значения устанавливаются, и последующий 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}
    />
  )
}

К сожалению, это не так, даже без выборки, просто жесткое кодирование значений тоже не работает. Единственная причина, по которой я включил пример как есть, потому что в противном случае мне сказали бы просто выполнить настройку переменной в конструкторе.

Matt Pengelly 02.04.2018 01:55

когда вы говорите, что жестко кодируете значения, вы имеете в виду в constructor() или в вызове setState()?

Anthony 02.04.2018 02:04
componentDidMount () { this.setState({ title: 'hello world' }) } Это дает тот же результат, что и при выборке. т.е.: title: "", content: "", catchPhrase: ""}
Matt Pengelly 02.04.2018 02:07
setState() также не обновляет состояние мгновенно. Попробуйте ввести значения для this.state = {} в constructor(), и я подозреваю, что это может сработать.
Anthony 02.04.2018 02:09

Однако мне нужно сделать выборку на серверной части. что, насколько я понимаю, это не то, что вы делаете в конструкторе

Matt Pengelly 02.04.2018 02:10

используя componentWillMount () (не componentDidMount), я могу установитьState ({title: 'hello world'}), хотя я все еще не могу заставить его работать с fetch (). Насколько я понимаю, componentDidMount предназначен для асинхронных действий и, следовательно, должен работать для этого?

Matt Pengelly 02.04.2018 02:16

Он будет работать, но компонент смонтирован так, что это означает, что обернутый компонент отрендерил, НО ваша выборка еще не решена.

Anthony 02.04.2018 02:17

Вы правы, поэтому кажется, что это потому, что componentDidMount в wrappedComponent вызывается слишком рано, и поскольку он вызывается только дважды, он не будет иметь правильных результатов. Он работает с условием, указанным вами выше. Спасибо!

Matt Pengelly 02.04.2018 02:24

есть ли более элегантный способ сделать это?

Matt Pengelly 02.04.2018 02:25

Позвольте нам продолжить обсуждение в чате.

Anthony 02.04.2018 02:26

Решение, указанное Тони, на самом деле было решением проблемы.

Matt Pengelly 15.05.2018 03:08

Другие вопросы по теме