繁体   English   中英

反应客户端componentDidMount不能正常工作(服务器端渲染)

[英]React client side componentDidMount not working properly (server side rendering)

你好Stackoverflow社区

如果我的解释不够清楚,请提前抱歉

当用户直接输入网址时。 服务器发出请求,获取相应的数据并呈现到屏幕。 这完美地工作

当用户单击链接时,该页面应该切换并呈现新组件,并通过componentDidMount从服务器获取相应数据并保存到状态,但由于某种原因该数据未显示在页面上

当我运行下面的代码时,console.log('2')出现在console.log('1')之前,这意味着在填充获取的数据之前,首先将状态呈现为未定义

它看起来像是一个异步问题,但我不知道解决该问题的方法,但事实并非如此,因为它适用于普通客户端应用程序

但是即使事件的顺序发生了扭曲,当状态更改没有发生时,应用也应该重新渲染。

News.js

import React from 'react';
import NewsList from './newslist';
import 'es6-promise'
import 'isomorphic-fetch';

class News extends React.Component {
  constructor(props){
    super(props)

    let initialData;

    if(props.staticContext){
      initialData = props.staticContext.initialData

    } else if (typeof window !== 'undefined') {
      initialData = window.__initialData__
      delete window.__initialData__
    }

    this.state = {news: initialData }
  }

  componentDidMount() {
    News.requestInitialData().then(data => {
      console.log('1 ' + data)                           <------- console log 1
    return this.setState({ news: data })
    });
    console.log('2 ' + this.state)                       <------- console log 2
  }

  static requestInitialData() {
    return fetch('http://localhost:3000/api/data')
    .then(response => response.json())
    .catch(err => console.log(err))
  }

  render() {
    return (
      <div className="App">
        <NewsList news={this.state.news} />
      </div>
    );
  }
}

module.exports = News

NewsList.js

import React, { Component } from "react";

export default class NewsList extends Component {
  constructor(props){
    super(props)

    // const data = (this.props.news) ? this.props.news : '';
    this.state = {news : this.props.news,
                  sortOrder: 'ascending'}
  }

  sortOrder(order, event) {
    event.preventDefault();
    const data = Object.assign([], this.state.news)
    let data2;

    if (order === 'ascending') {
      data.sort( (a,b) => a.id - b.id )
      data2 = 'ascending'
    }
    else if (order === 'descending') {
      data.sort( (a,b) => b.id - a.id )
      data2 = 'descending'
    }

    this.setState({ 
      news: data,
      sortOrder: data2
    });
  }

  render() {
    const news = this.state.news

    return (
      <div>
        <div className="sort">
            <a
              href="#"
              className={"ascending"}
              onClick={this.sortOrder.bind(this, "ascending")}>
              Ascending
            </a>|
            <a
              href="#"
              className={"descending"}
              onClick={this.sortOrder.bind(this, "descending")}>
              Date
            </a>
          </div>


        {news && news.map(post =>
          <div key={post.id} className="news-item">
              <p>
                <span className="news-position">{post.id}. ▲</span> {post.title}{" "}
                <small>(by {post.author})</small>
              </p>
              <small className="news-details">
                {post.upvotes} upvotes
              </small>
          </div>
        )}
      </div>
    );
  }
}

在此先感谢您的帮助

您的代码看起来不错。 正在发生以下情况:

componentDidMount您请求初始数据。 这是一个异步操作,这意味着componentDidMount将在不等待其完成的情况下完成,并且console.log('2 ' + this.state)将被执行,并且在此初始呈现之后将被调用,而没有任何数据。

然后requestInitialData完成,并且您看到console.log('1 ' + data)记录。 之后,您更新状态(请注意setState也是异步的),并且News将再次使用数据呈现。

ui未被更新的原因可能是NewsList工具应执行shouldComponentUpdate并且在某些情况下不会重新呈现自身。

我建议将日志记录在NewsNewsList render方法中,看看它们如何被调用。 并且您确实从requestInitialData方法获取数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM