React – Working with Data

After learning the fundamental concepts of prop and state, the next thing to learn is how data is handled in React. Data can be a user’s detail, list of products, and so on. It is everywhere and inevitable.

A good application always organizes and properly uses the data(state and props). We will learn how data flows in react, correct props and state usage, and explore many useful techniques to work with data.

Data Flow Pattern in React

React allows only the unidirectional flow of data from the parent component to the child component. Data can never flow backward from the child component to the parent component.

So, any data (state or props) of a component cannot be passed back to its parent (if any). It is the parent that can pass data (state or props) forwards to its child.

This is in contrast to other JavaScript frameworks like Angular, where data can flow back and forth.

This has its benefits, though:

  • It keeps the data (state or prop) organization simple and easy to track.
  • It reduces unwanted confusion and bugs as the data grows.

Updating a parent’s state

All components can update their state. But what if we had a button inside a child component that needs to update its parent’s state?

The solution is to give the power to the child component for updating the parent’s state. Here are the steps:

  1. Define a function inside the parent component that will update its state(the parent component).
  2. Pass that function as a prop to its child component.
  3. The child component now can update the parent’s state by calling that prop function.

Therefore, using this technique, we can indirectly update a parent component’s state.

Let’s take the example below:

// parent's state
state = {
    count: 0
}
/*
define a method in the parent component that
will update the state.
*/
updateCount = (num) => {
        this.setState({
            count: num
        })
    }
    /*
    and inside render(), pass the method to the child component
    so that the Child can also update the state...
    */
    <div>
    < Child num = {
        count
    }
updateNum = {
    this.updateCount
}/> </div>

Now in the child component, the props will be available. We can add a button to update the parent’s “count” state every time a user clicks it.

function Child(props) {
    /* es6 object destructring to get the props */
    const {
        num,
        updateNum
    } = props
    return ( <div>
        <h2> {
            num
        } </h2> <
        button onClick = {
            () => updateNum(num + 1)
        } >
        Update Count 
        </button> 
             </div>
    )
}

When the button “Update Count” is clicked, it will update the parent’s state. In this way, we can update a parent component’s state by passing a state updater function as a prop.

State Lifting

State lifting is the action of moving the state upwards in the component tree to a common parent so that all the child components that require this state can access it.

The diagram below shows a “child 1” component that has a “count” state, but at some point later, “child 2” also decides to use it. They both have a common parent component.

The solution is to move the “count” state to the nearest common ancestor.

This is called Lifting State Up. Moving the state upwards in the component tree will ensure that all the child components need the state to receive it through props.

Do not move the state unnecessarily too high in the component tree. Always move the required state to the closest ancestor of the components that need it.

Rendering a list of data

Components are reusable, and most of the time, we face the need for rendering a list of data. There are plenty of examples: Youtube renders a list of videos, Facebook renders a list of posts, and so on.

These use a similar type of component when rendering a list of data, which is an array.

JavaScript has a higher-order function called .map() using which you can render multiple JSX elements/components.

The example below renders a list of items…

function ItemsList(props) {
    const {
        items
    } = props
    return ( <h1> Items </h1> 
              <ul> {
                items.map(item => 
                 <li> { item } </li>)} 
              </ul>
                )
            }

We can pass the array as a prop like below:

const itemList = [‘Phone', ‘Keyboard’, ‘Monitor’]
<ItemsList items={ itemList } />

The .map() method takes a function that should return a JSX element or a component for each array element. The result of the above code will be displayed as a list of items:

Items

  • Phone
  • Keyboard
  • Monitor

We used the <li> tag for rendering lists. But you can replace that with components that can do much more than that. We can also render an array of arrays, an array of objects, and not just simple arrays.

Controlled Components

We have to deal with forms in most web applications. How do you get the data from the form inputs once a user submits the form? It turns out that there are two solutions: controlled and uncontrolled components.

In controlled components, we sync the form input value with the state so that, whenever the form input is updated, the state will also change to update itself. This will allow us to use the latest value of the input from the state.

When the values are in sync, then the component is said to be controlled where:

  1. Any change in the state updates the form value.
  2. Any change in the form value updates the state.

To make forms controlled, we need to use the onChange event and the value attribute on the form input. The example below shows a controlled form of input.

class Form extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: ''
        }
    }
    render() {
        const {
            name
        } = this.state
        return ( <div>
            Name:
            <input type = 'text'
            value = {name}
            onChange = { e =>
                this.setState({
                    name: e.target.value
                })
            }/> 
                   </div>
        )
    }
}

This kind of component is a controlled component.

We can also use other methods like React Refs to get the value of the form on submit/some other event. It will then be an uncontrolled component.

Summary

Learning to manage and organize data, state, and props is a very important skill in React. You may learn the methods, but this skill can only be improved over time with practice.

It may be difficult to grasp all at once, but you will encounter them sooner and later in your React Developer career.

Back to: React Tutorial > Learn React

Leave a Reply

Your email address will not be published. Required fields are marked *