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.
Follow
asked Jun 29, 2016 at 13:46
19111 gold badge22 silver badges1212 bronze badges
ANSWER
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;
Follow
answered Jun 29, 2016 at 15:22
6,53422 gold badges1717 silver badges3434 bronze badges
1
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)
Report this ad
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;
Follow
answered Jun 29, 2016 at 13:50
6,55511 gold badge2020 silver badges2121 bronze badges
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 incomponentWillMount
andcomponentWillReceiveProps
– Brandon