Skip to content

Instantly share code, notes, and snippets.

@amcooper
Last active August 2, 2017 00:29
Show Gist options
  • Save amcooper/57fbb5dcee8ca62d20176b94ec9aa9ed to your computer and use it in GitHub Desktop.
Save amcooper/57fbb5dcee8ca62d20176b94ec9aa9ed to your computer and use it in GitHub Desktop.
Vigilant snippet no. 2

Snippet no. 2: React components for composing a list of tweets

Why did I write this?

This is a first stab at constructing a front end to incorporate the previously discussed Lesser Evil CLI gem. It consists of a Tweet component, which, for now, displays the key elements of a tweet (text, author, and timestamp), and a TweetList component, which is designed to respond to changes in the database as the gem trawls for the tweets it's looking for and adds them. As of yet, there is no database, so I built a seed file and a simulator that adds tweets from the seed file to the TweetList state at random intervals.

What does it do?

  • After the TweetList is attached to the DOM (in a separate file), it's rendered by mapping an array of Tweet components to the tweets array in the state (line 50). This array is empty at first (line 23).
  • Once the component is mounted the componentDidMount method is called (line 45). Here we iterate over the tweets from the seed file and call the wrapper method for the setTimeout functionality.
  • setTimeoutWrapper (line 36) sets up a delay window of 2 seconds and makes a call to readNextTweet at a random point within that window.
  • readNextTweet (line 27) grabs the next tweet from the seed array and pushes it onto the state's tweets array. This state update triggers a re-render of the TweetList component in the DOM, i.e., the addition of the next tweet to the list.
import React, { Component } from 'react';
import './App.css';
import seedTweets from './seeds.js';
class Tweet extends Component {
render() {
return(
<div className="tweet">
<p className="tweetText">{ this.props.text }</p>
<p className="tweetMetadata">
<span className="tweetAuthor">{ this.props.author }</span>
<span className="tweetTime">{ this.props.time.toString() }</span>
</p>
</div>
)
}
}
class TweetList extends Component {
constructor() {
super();
this.state = {
tweets: []
};
}
readNextTweet( index ) {
var currentTweets = this.state.tweets;
var tweet = seedTweets[index];
currentTweets.push( tweet );
this.setState((prevState, props) => ({
tweets: currentTweets
}));
}
setTimeoutWrapper( index ) {
const min = 1000 + ( index * 2000 );
const max = 3000 + ( index * 2000 );
setTimeout(
function() { this.readNextTweet( index ); }.bind( this ),
Math.random() * ( max - min ) + min
)
}
componentDidMount() {
seedTweets.forEach( (c,i,a) => { this.setTimeoutWrapper( i ); });
}
render() {
const tweetItems = this.state.tweets.map(
tweet =>
<Tweet
key={tweet.time.toString()}
text={tweet.text}
author={tweet.author}
time={tweet.time}
/>
);
return (
<div className="tweetList">{ tweetItems }</div>
)
}
}
class App extends Component {
render() {
return (
<TweetList />
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment