Skip to content
This repository was archived by the owner on Dec 4, 2018. It is now read-only.

Commit 3bf0843

Browse files
author
Dzikri Aziz
committed
Fix loading state of the Post page
See reduxjs/react-redux#210
1 parent 9ef8b84 commit 3bf0843

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

app/pages/Post.jsx

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,29 @@ class Post extends Component {
2020
fetchPost
2121
]
2222

23+
static propTypes = {
24+
slug: PropTypes.string.isRequired,
25+
info: PropTypes.object.isRequired,
26+
singular: PropTypes.object.isRequired,
27+
dispatch: PropTypes.func.isRequired
28+
}
29+
30+
constructor( props ) {
31+
super( props )
32+
33+
/**
34+
* State
35+
*
36+
* When `slug` exists, it means this component is rendered by the server.
37+
*
38+
* @type {Object}
39+
* @see {@link https://github.com/reactjs/react-redux/issues/210}
40+
*/
41+
this.state = {
42+
isWaitingForProps: ! props.singular.data.slug
43+
}
44+
}
45+
2346
/**
2447
* Before mount
2548
*
@@ -30,9 +53,15 @@ class Post extends Component {
3053
* store doesn't match the requested page.
3154
*/
3255
componentWillMount() {
33-
const { slug, data, isFetching, dispatch } = this.props
56+
const { slug, singular, dispatch } = this.props
57+
const { data, isFetching } = singular
58+
59+
if ( isFetching ) {
60+
this.setState({ isWaitingForProps: false })
61+
return
62+
}
3463

35-
if ( ! isFetching && slug !== data.slug ) {
64+
if ( slug !== data.slug ) {
3665
dispatch( fetchPost({ slug }) )
3766
}
3867
}
@@ -46,11 +75,19 @@ class Post extends Component {
4675
* @param {object} nextProps Next properties.
4776
*/
4877
componentWillReceiveProps( nextProps ) {
49-
const { slug, isFetching, dispatch } = nextProps
78+
const { slug, singular, dispatch } = nextProps
79+
const { data, isFetching } = singular
5080

51-
if ( ! isFetching && slug !== this.props.slug ) {
52-
dispatch( fetchPost({ slug }) )
81+
if ( isFetching ) {
82+
this.setState({ isWaitingForProps: false })
83+
return
84+
}
85+
86+
if ( slug === this.props.slug ) {
87+
return
5388
}
89+
90+
dispatch( fetchPost({ slug }) )
5491
}
5592

5693
/**
@@ -59,10 +96,11 @@ class Post extends Component {
5996
* TODO: Render meta, comments, etc.
6097
*/
6198
render() {
62-
const { info, data, isFetching } = this.props
99+
const { info, singular } = this.props
100+
const { data, isFetching } = singular
63101
let title
64102

65-
if ( isFetching ) {
103+
if ( isFetching || this.state.isWaitingForProps ) {
66104
return ( <Spinner /> )
67105
} else if ( ! data.id ) {
68106
return ( <NotFound /> )
@@ -87,21 +125,13 @@ class Post extends Component {
87125
}
88126
}
89127

90-
Post.propTypes = {
91-
slug: PropTypes.string.isRequired,
92-
info: PropTypes.object.isRequired,
93-
data: PropTypes.object,
94-
isFetching: PropTypes.bool.isRequired,
95-
dispatch: PropTypes.func.isRequired
96-
}
97-
98128
function mapStateToProps( state, ownProps ) {
99129
const { slug } = ownProps.params
100130

101131
return {
102132
slug: slug,
103133
info: state.info,
104-
...state.singular
134+
singular: state.singular
105135
}
106136
}
107137

app/reducers/singular.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ export default function singular( state = initialState, action ) {
1717
switch ( action.type ) {
1818
case GET_SINGULAR_REQUEST:
1919
return Object.assign( {}, state, {
20+
data: {},
2021
isFetching: true
2122
});
2223

2324
case GET_SINGULAR_SUCCESS:
2425
let data = head( action.req.data, 1 );
2526

26-
// Page/post not found.
27+
/**
28+
* Page/post not found.
29+
*
30+
* We need to store the `slug` so the component will know
31+
* that we've already requested the page.
32+
*/
2733
if ( ! data ) {
2834
data = {
2935
slug: action.req.config.params.slug,

0 commit comments

Comments
 (0)