1

I will try and make this as short and sweet as possible while being detailed and descriptive. When my application initializes or loads for the first time, it makes an api call to fetch some blog data. Here is what that looks like more or less:

Redux State Store

As you can see the api successfully returns the blogPosts. I then reference these blogPosts in another component using createStructuredSelector from the reselect library. Here is the code:

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';

import VisionBlogItem from '../../components/VisionBlogItem';
import { getBlogItem, getFollowingBlogItems } from './selectors';

export class VisionBlogItemPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props, context) {
    super(props, context);

    this.state = {
    };

  }

  render() {
    return (
      <div>
        {this.props.blogItem && <VisionBlogItem blog={this.props.blogItem} blogItems={this.props.blogItems} />}
      </div>
    );
  }
}

VisionBlogItemPage.propTypes = {
  dispatch: PropTypes.func.isRequired,
  location: PropTypes.shape({
    pathname: PropTypes.string.isRequired,
  }),
  blogItem: PropTypes.object,
  blogItems: PropTypes.array,
};

VisionBlogItemPage.defaultProps = {
  blogItem: {},
  blogItems: [],
};

const mapStateToProps = (state, ownProps) => {
  return createStructuredSelector({
    blogItem: getBlogItem(ownProps.location.pathname.match(/([^/]*)\/*$/)[1]),
    blogItems: getFollowingBlogItems(ownProps.location.pathname.match(/([^/]*)\/*$/)[1])
  });
};

function mapDispatchToProps(dispatch) {
  return {
    dispatch,
  };
}

const withConnect = connect(mapStateToProps, mapDispatchToProps);

export default compose(
  withConnect,
)(VisionBlogItemPage);

What these selector methods are doing, getBlogItem and getFollowingBlogItems, are checking the props location pathname end slug and using it to iterate and array to find the needed blog in the Redux State Store. They then get set to the props named blogItem and blogItems to be passed to the presentational component to render. That presentational component looks something like this:

wireframe

At the bottom of this presentational component are some links that will change the slug name. So if I'm at localhost:3000/blogPosts/blog-post-0 and I clicked on one of the three blog posts at the bottom, it would then change the url to localhost:3000/blogPosts/blog-post-1 or blog-post-2, blog-post-3, etc. These blog posts at the bottom are links from react-router-dom and the code is written as such:

<Link to={props.blogItems[2].fields.slug} style={styles.seeMoreLink}>
  <img src={props.blogItems[2].fields.articleImage.fields.file.url} style={styles.seeMoreImg} alt="" key="2" />
</Link>

So the idea is that it changes the slug of the url and renders the appropriate blog post. However, this is not what is occurring. The url slug does change and I can even see in my container component that the props update and change as well. The location pathname changes from blog-post-1 to blog-post-2. My question then lies why does my component not re-render? I am aware of the life-cycle method of componentWillReceiveProps, but I do not know how to use it in conjunction with something like createStructuredSelector from reselect. Anyone who could possibly give me a clear path as to how I am suppose to handle this it would be greatly appreciated!

Nappstir
  • 995
  • 2
  • 20
  • 38

0 Answers0