[英]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并且在某些情况下不会重新呈现自身。
我建议将日志记录在News
和NewsList
render方法中,看看它们如何被调用。 并且您确实从requestInitialData
方法获取数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.