我使用Router像下面的代码那样在组件之间切换,包括Home,Sidebar,Detail,Category。
对于第一次加载,它将显示所有最近的帖子,特色帖子。 当我单击某个帖子以查看详细信息时,效果很好。 在详细信息页面中,我单击以渲染新帖子,但不渲染。
我的代码:
null
请查看照片:
我的详细信息:
class App extends React.Component {
render () {
// if ('serviceWorker' in navigator) {
// const registration = runtime.register();
// }
module.hot.accept();
$("body").removeClass();
$("body").addClass("homepage");
<Helmet>
<title>{blog_title}</title>
<meta name="description" content={blog_description} />
</Helmet>
const {feature, main, sidebar, mainbottom, header } = this.props;
return (
<div id="all">
{header}
<div className="container">
<div className="main-feature" id="main-feature">
{feature}
</div>
</div>
<div id="content" className="site-content">
<div className="container">
<div className="divcontainer">
<div id="po-homepage" className="content-area">
{main}
</div>
<aside id="secondary" className="sidebar widget-area">
<div className="popular_post" id="popular_post">
{sidebar}
</div>
</aside>
</div>
</div>
</div>
<div className="cat-list">
<div className="container">
<div className="thecategories" id="thecategories">
{mainbottom}
</div>
</div>
</div>
</div>
)
}
}
当我添加ComponentDidUpdate()时,它可以工作,但是在渲染新帖子之前先渲染回环顶部的细节。我这样使用。
import React, {Component} from "react"; //nếu chỉ import React thì sẽ cần React.Component
import $ from 'jquery';
import { Helmet } from "react-helmet";
import {
BrowserRouter as Router,
Route,
Switch
} from 'react-router-dom';
class Detail extends React.Component {
constructor(props) {
super(props);
this.state = {
post: {}
};
}
componentDidMount() {
//scroll to detail
$(document).ready(function(){
$("html, body").animate({ scrollTop: $("#content").offset().top - 100 }, 500);
$("body").removeClass();
$("body").addClass("detailpage");
});
console.log(this.props.detailink);
var that = this;
var url = window.location.href.split("/");
var slug = url.pop() || url.pop();
// console.log(CelestialSettings.URL.api + "/posts?slug=" + slug);
fetch(CelestialSettings.URL.api + "/posts?slug=" + slug)
.then(function(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response.json();
})
.then(function(res) {
that.setState({ post: res[0] });
});
}
renderPosts() {
return (
<div className="card">
<div className="card-body">
<Helmet>
<title>{this.state.post.title.rendered}</title>
<meta name="description" content={this.state.post.excerpt.rendered.replace(/<\/?[^>]+(>|$)/g, "")} />
</Helmet>
<h1 className="card-title">{this.state.post.title.rendered}</h1>
<p className="card-text">
<small className="text-muted">
{this.state.post.author_name} –{" "}
{this.state.post.published_date}
</small>
</p>
{this.state.post.featured_image_src ? (
<img
className="featured-image"
src={this.state.post.featured_image_src}
alt="featured image"
/>
) : null}
<p
className="card-text"
dangerouslySetInnerHTML={{
__html: this.state.post.content.rendered
}}
/>
</div>
</div>
);
}
renderEmpty() {
return (
<div></div>
);
}
render() {
var href = window.location.href+"/?view=react";
return (
<div className="container post-entry">
{this.state.post.title ? this.renderPosts() : this.renderEmpty()}
</div>
);
}
}
export default Detail;
对我的问题有任何建议吗?非常感谢。
答案 0 :(得分:2)
您的Detail
组件需要知道url发生了更改,并且由于在尝试呈现时未传递任何相关属性,因此您必须使用react路由器提供的withRouter
HOC
因此在“详细信息”组件文件的顶部
import {
BrowserRouter as Router,
Route,
Switch,
withRouter // add this (and the comma in the above line)
} from 'react-router-dom';
在export
使用的底部
export default withRouter(Detail);
更新
多读一些Details
代码,我发现您fetch
生命周期事件中的内容ComponentDidMount
,但是当您加载新帖子时,您将停留在同一页面上,因此Details
组件未卸载/重新安装,只是使用新的道具进行了更新,因此ComponentDidMount
不会再次触发。您还必须使用ComponentDidUpdate
一些其他信息
由于您正在使用react-router,因此您不应该自己解析window.location.href
来试图解决这一问题。您可以自动将其从路由器提供的道具中传下来。
<!-- language: lang-js -->
<Route
path={CelestialSettings.path + 'posts/:slug'}
render={(props) => <App header={<Header/>}
main={<Detail slug={props.match.slug} detailink={CelestialSettings.path + 'posts/:slug'} />}
sidebar={<Popular />}
feature={<Featurex/>}
mainbottom={<Categories/>} />} />
然后在您的ComponentDidUpdate
<!-- language: lang-js -->
componentDidUpdate(newProps) {
const {slug} = newProps;
const that = this; // you do not need this if you use arrow functions
if (slug !== this.props.slug) {
fetch(CelestialSettings.URL.api + "/posts?slug=" + slug)
.then(function(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response.json();
})
.then(function(res) {
that.setState({
post: res[0]
});
});
}
}