This function references CollectionTweets that are stored in the current state, adds a new tweet to a collectionTweets object, and updates the state by calling the setState() function. A new tweet is passed as an argument when the addTweetToCollection() function is called inside a Stream component. This is an example of how a child component can update its parent component’s state.

This an important mechanism in React and it works as follows:

  1. A parent component passes a callback function as a property to its child component. A child component can access this callback function via the this.props variable.
  2. Whenever a child component wants to update the parent component’s state, it calls that callback function and passes all the necessary data to a new parent component’s state.
  3. A parent component updates its state, and as you already know, this state updates and triggers the render() function that re-renders all the child components, as necessary.

This is how a child component interacts with a parent component. This interaction allows a child component to delegate the application’s state management to its parent component, and it is only concerned with how to render itself. Now, when you’ve learned this pattern, you will be using it again and again because most of your React components should stay stateless. Only a few parent components should store and manage your application’s state. This best practice allows us to logically group React components by the two different concerns that they address:

  • Manage the application’s state and render
  • Only render and delegate the application’s state management to a parent component

Our Application component has a second child component, Collection:

<Collection
  tweets={this.state.collectionTweets}
  onRemoveTweetFromCollection={this.removeTweetFromCollection}
onRemoveAllTweetsFromCollection={this.removeAllTweetsFromCollection} />

This component has a number of properties:

  • tweets: This refers to our current collection of tweets
  • onRemoveTweetFromCollection: This refers to a function that removes a particular tweet from our collection
  • onRemoveAllTweetsFromCollection: This refers to a function that removes all the tweets from our collection

You can see that the Collection component’s properties are only concerned about how to:

  • Access the application’s state
  • Mutate the application’s state

As you can guess, the onRemoveTweetFromCollection and onRemoveAllTweetsFromCollection functions allow the Collection component to mutate the Application component’s state. On the other hand, the tweets property propagates the Application component’s state to the Collection component so that it can gain a read-only access to that state.

Can you recognize the single direction of data flow between the Application and Collection components? Here’s how it works:

  1. The collectionTweets data is initialized in the Application component’s getInitialState() method.
  2. The collectionTweets data is passed to the Collection component as the tweets property.
  3. The Collection component calls the removeTweetFromCollection and removeAllTweetsFromCollection functions that update the collectionTweets data in the Application component, and the cycle starts again.

Notice that the Collection component cannot directly mutate the Application component’s state. The Collection component has read-only access to that state via this.props object, and the only way to update the parent component’s state is to call the callback functions that are passed by the parent component. In the Collection component, these callback functions are this.props.onRemoveTweetFromCollection and this.props.onRemoveAllTweetsFromCollection.

This simple mental model of how data flows in our React component hierarchy will help us increase the number of components we use, without increasing the complexity of how our user interface works. For example, it can have 10 levels of nested React components, as follows:

Creating a container React component
If Component G wants to mutate the state of root Component A, it would do it in the exact same way that Component B, or Component F, or any other component in this hierarchy would. However, in React, you shouldn’t pass data from Component A directly to Component G. Instead, you should first pass it to Component B, then to Component C, then to Component D, and so on until you finally reach Component G. Component B to Component F will have to carry some “transit” properties that are actually only meant for Component G. This might look like a waste of time, but this design makes it easy for us to debug our application and be able to reason out how it works. There are always strategies to optimize your application’s architecture. One of them is to use Flux, which we’ll discuss later in this book.

Before we finish discussing our Application component, let’s take a look at the two methods that mutate its state:

removeTweetFromCollection: function (tweet) {
  var collectionTweets = this.state.collectionTweets;

  delete collectionTweets[tweet.id];

  this.setState({
    collectionTweets: collectionTweets
  });
},

The removeTweetFromCollection() method removes a tweet from a collection of tweets that we store in the Application component’s state. It takes the current collectionTweets object from the component’s state, deletes a tweet with a given ID from that object, and updates the component’s state with an updated collectionTweets object.

On the other hand, the removeAllTweetsFromCollection() method removes all the tweets from the component’s state:

removeAllTweetsFromCollection: function () {
  this.setState({
    collectionTweets: {}
  });
},

Both of these methods are called from a child’s Collection component because that component has no other way to mutate the Application component’s state.

This function references CollectionTweets that are stored in the current state, adds a new tweet to a collectionTweets object, and updates the state by calling the setState() function. A new tweet is passed as an argument when the addTweetToCollection() function is called inside a Stream component. This is an example of how a child component can update its parent component’s state.

This an important mechanism in React and it works as follows:

  1. A parent component passes a callback function as a property to its child component. A child component can access this callback function via the this.props variable.
  2. Whenever a child component wants to update the parent component’s state, it calls that callback function and passes all the necessary data to a new parent component’s state.
  3. A parent component updates its state, and as you already know, this state updates and triggers the render() function that re-renders all the child components, as necessary.

This is how a child component interacts with a parent component. This interaction allows a child component to delegate the application’s state management to its parent component, and it is only concerned with how to render itself. Now, when you’ve learned this pattern, you will be using it again and again because most of your React components should stay stateless. Only a few parent components should store and manage your application’s state. This best practice allows us to logically group React components by the two different concerns that they address:

  • Manage the application’s state and render
  • Only render and delegate the application’s state management to a parent component

Our Application component has a second child component, Collection:

<Collection
  tweets={this.state.collectionTweets}
  onRemoveTweetFromCollection={this.removeTweetFromCollection}
onRemoveAllTweetsFromCollection={this.removeAllTweetsFromCollection} />

This component has a number of properties:

  • tweets: This refers to our current collection of tweets
  • onRemoveTweetFromCollection: This refers to a function that removes a particular tweet from our collection
  • onRemoveAllTweetsFromCollection: This refers to a function that removes all the tweets from our collection

You can see that the Collection component’s properties are only concerned about how to:

  • Access the application’s state
  • Mutate the application’s state

As you can guess, the onRemoveTweetFromCollection and onRemoveAllTweetsFromCollection functions allow the Collection component to mutate the Application component’s state. On the other hand, the tweets property propagates the Application component’s state to the Collection component so that it can gain a read-only access to that state.

Can you recognize the single direction of data flow between the Application and Collection components? Here’s how it works:

  1. The collectionTweets data is initialized in the Application component’s getInitialState() method.
  2. The collectionTweets data is passed to the Collection component as the tweets property.
  3. The Collection component calls the removeTweetFromCollection and removeAllTweetsFromCollection functions that update the collectionTweets data in the Application component, and the cycle starts again.

Notice that the Collection component cannot directly mutate the Application component’s state. The Collection component has read-only access to that state via this.props object, and the only way to update the parent component’s state is to call the callback functions that are passed by the parent component. In the Collection component, these callback functions are this.props.onRemoveTweetFromCollection and this.props.onRemoveAllTweetsFromCollection.

wrapping up

In this Guide, we learned how to solve a problem with React. We started by breaking down the problem into smaller individual problems and then discussed how we can address them using React. Then, we created a list of React components that we needed to implement. Finally, we created our first composable React component and learned how a parent component interacts with its child components. In the next Guide, we’ll implement our child components and learn about React’s lifecycle methods.