Next, let's refactor our Collection
component. Replace the existing Collection
component with an updated one:
var React = require('react'), var ReactDOMServer = require('react-dom/server'), var CollectionControls = require('./CollectionControls.react'), var TweetList = require('./TweetList.react'), var Header = require('./Header.react'), var CollectionUtils = require('../utils/CollectionUtils'), var CollectionStore = require('../stores/CollectionStore'), var Collection = React.createClass({ getInitialState: function () { return { collectionTweets: CollectionStore.getCollectionTweets() } }, componentDidMount: function () { CollectionStore.addChangeListener(this.onCollectionChange); }, componentWillUnmount: function () { CollectionStore.removeChangeListener(this.onCollectionChange); }, onCollectionChange: function () { this.setState({ collectionTweets: CollectionStore.getCollectionTweets() }); }, createHtmlMarkupStringOfTweetList: function () { var htmlString = ReactDOMServer.renderToStaticMarkup( <TweetList tweets={this.state.collectionTweets} /> ); var htmlMarkup = { html: htmlString }; return JSON.stringify(htmlMarkup); }, render: function () { var collectionTweets = this.state.collectionTweets; var numberOfTweetsInCollection = CollectionUtils.getNumberOfTweetsInCollection(collectionTweets); var htmlMarkup; if (numberOfTweetsInCollection > 0) { htmlMarkup = this.createHtmlMarkupStringOfTweetList(); return ( <div> <CollectionControls numberOfTweetsInCollection={numberOfTweetsInCollection} htmlMarkup={htmlMarkup} /> <TweetList tweets={collectionTweets} /> </div> ); } return <Header text="Your collection is empty" />; } }); module.exports = Collection;
What did we change here ? A few things. First, we imported two new modules:
var CollectionUtils = require('../utils/CollectionUtils'), var CollectionStore = require('../stores/CollectionStore'),
We created the CollectionUtils
module in Chapter 8, Test Your React Application with Jest, and in this chapter, we're using it. CollectionStore
is where we get our data from.
Next, you should be able to spot the familiar pattern of the four methods:
getInitialState()
method, we set the collection of tweets to what is stored in CollectionStore
at that moment. As you may recall that CollectionStore
provides the getCollectionTweets()
method to get the data from it.componentDidMount()
method, we add the change
event listener, this.onCollectionChange
, to CollectionStore
. Whenever the collection of tweets is updated, CollectionStore
will call our this.onCollectionChange
callback function to notify the Collection
component of that change.componentWillUnmount()
method, we remove the change
event listener that we added to the componentDidMount()
method.onCollectionChange()
method, we set the component's state to whatever is stored in CollectionStore
at that moment in time. Updating the component's state triggers re-rendering.The Collection
component's render()
method is now simpler and cleaner:
render: function () { var collectionTweets = this.state.collectionTweets; var numberOfTweetsInCollection = CollectionUtils.getNumberOfTweetsInCollection(collectionTweets); var htmlMarkup; if (numberOfTweetsInCollection > 0) { htmlMarkup = this.createHtmlMarkupStringOfTweetList(); return ( <div> <CollectionControls numberOfTweetsInCollection={numberOfTweetsInCollection} htmlMarkup={htmlMarkup} /> <TweetList tweets={collectionTweets} /> </div> ); } return <Header text="Your collection is empty" />; }
We use the CollectionUtils
module to get a number of tweets in the collection, and we pass fewer properties to the child components: CollectionControls
and TweetList
.
3.147.140.206