8

I just started learning React in my work and I need to build a blog using React. I need to show random posts as "recommended Posts", after doing some research I found a possible solution, using Math.random() but I could not figure it out how to implement it in my component.

This is my code:

RecommendedPost/index.js

import React from 'react';
import { Link } from 'react-router';

class RecommendedPosts extends React.Component {

render() {
return (
  <ul>
    {this.props.posts.map((post, idx) => {
      return (
        <li key={idx}>
          <p>{post.title}</p>
          <p>{post.text}</p>
          <p>{post.category}</p>
          <Link to={`/blog/post-1/:${post.id}`}>Weiter lesen</Link>
        </li>
      );
    })}
  </ul>
);
}
}
RecommendedPosts.propTypes = {
posts: React.PropTypes.array,
};
export default RecommendedPosts;

Then I use this component in my container: BlogPage/SinglePostPage/index.js

import React from 'react';
// ...other imported stuff
import RecommendedPosts from 'components/Blog/RecommendedPosts';

class PostPage extends React.Component {

render() {
  // dummy-recomended-posts
const posts = [
  {
    id: 1,
    title: 'How to Cook Blue Meth',
    description: 'Lorem ipsum dolor sit amet, turpis at, elit',
    thump: 'thump.jpg',
    hero: '/img/',
    category: 'k1',
    fullname: 'Walter White',
    published: '10.05.2016, 15:30pm',
  },
  {
    id: 2,
    title: 'Passenger',
    description: 'Lorem ipsum dolor sit amet, turpis at, elit',
    thump: 'thump.jpg',
    hero: '/img/',
    category: 'k2',
    fullname: 'Chino Moreno',
    published: '10.05.2016, 15:30pm',
   },
    // ...and more dummy posts(about 7)
   ];
return (
   <div>
   // here, I pass the posts array to my component
   <RecommendedPosts posts={posts} />
   </div>
  );
  }
 }
}
export default connect(null, mapDispatchToProps)(PostPage);

My idea is to render the posts randomly using the id as a ref but again I can't find the way.

Hope some one can help me, and sorry if the answer is too obvious for everyone.

3 Answers 3

19

I went ahead and created a working example for you

import React from 'react';
import { Link } from 'react-router';

function shuffleArray(array) {
  let i = array.length - 1;
  for (; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    const temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

class RecommendedPosts extends React.Component {
  render() {
    const shuffledPosts = shuffleArray(this.props.posts);
    return (
      <ul>
        {shuffledPosts.map((post) => {
          return (
            <li key={post.id}>
              <p>{post.title}</p>
              <p>{post.text}</p>
              <p>{post.category}</p>
              <Link to={`/blog/post-1/:${post.id}`}>Weiter lesen</Link>
            </li>
          );
        })}
      </ul>
    );
  }
}
RecommendedPosts.propTypes = {
  posts: React.PropTypes.array,
};
export default RecommendedPosts;

Bonus tip - since you're not using state or lifecycle, you can create a much simpler functional component as such:

import React from 'react';
import { Link } from 'react-router';

function shuffleArray(array) {
  let i = array.length - 1;
  for (; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    const temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

function RecommendedPosts({ posts }) {
  const shuffledPosts = shuffleArray(posts);
  return (
    <ul>
      {shuffledPosts.map((post) => {
        return (
          <li key={post.id}>
            <p>{post.title}</p>
            <p>{post.text}</p>
            <p>{post.category}</p>
            <Link to={`/blog/post-1/:${post.id}`}>Weiter lesen</Link>
          </li>
        );
      })}
    </ul>
  );
}
RecommendedPosts.propTypes = {
  posts: React.PropTypes.array,
};
export default RecommendedPosts;
Sign up to request clarification or add additional context in comments.

2 Comments

That was just amazing! Thank you so much!....and also thanks to everyone who help to improve this question! I guess I have a lot to learn and I want to try doing this with states and lifecycles!
key={idx} will cause un-mounting and re-mounting of the child component on every re-render of RecommendedPosts, we can avoid that if we use fixed Key for each child(let's say original index of each child)
3

In your Recommended post first shuffle the posts and store it in state and then render

import React from 'react';
import { Link } from 'react-router';

class RecommendedPosts extends React.Component {

constructor() {
super(props);
this.state = {
posts: this.shuffle(this.props.posts)
}
}

shuffle(posts){
 ///shuffle using some algo
return posts
}

render() {
return (
  <ul>
    {this.state.posts.map((post, idx) => {
      return (
        <li key={idx}>
          <p>{post.title}</p>
          <p>{post.text}</p>
          <p>{post.category}</p>
          <Link to={`/blog/post-1/:${post.id}`}>Weiter lesen</Link>
        </li>
      );
    })}
  </ul>
);
}
}
RecommendedPosts.propTypes = {
posts: React.PropTypes.array,
};
export default RecommendedPosts;

1 Comment

using props in your constructor is an antipattern. Just shuffle the posts at the top of render: const postsToRender = this.shuffle(this.props.posts). If you really want to store it in state, then do the shuffling in componentWillMount and componentWillReceiveProps
1

you can use lodash shuffle function to randomize your array and then simply render by taking data from that array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.