# Lifting State Up

## Referennces

Lifting State Up – React official Docs\
<https://reactjs.org/docs/lifting-state-up.html>

Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let’s see how this works in action.

There should be a single “source of truth” for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, you should rely on the [top-down data flow](https://reactjs.org/docs/state-and-lifecycle.html#the-data-flows-down).

Lifting state involves writing more “boilerplate” code than two-way binding approaches, but as a benefit, it takes less work to find and isolate bugs. Since any state “lives” in some component and that component alone can change it, the surface area for bugs is greatly reduced. Additionally, you can implement any custom logic to reject or transform user input.

If something can be derived from either props or state, it probably shouldn’t be in the state.

## Example

Let's see a concrete example. Let say you have 2 components that need to communicate with each other: An `InputFilter` component and a `ProductList` component that are both connected within `App`.

```jsx
function InputFilter(props) {
  return (
    <input type="text">
  );
}

function ProductList(props) {  
  const productList = props.products.map((product) => {
    return (<li>{product.name}</li>)
  });

  return (
    <ul>
      {productList}
    </ul>
  )
}

class App extends React.Component {
  render() {
    return (
      <div>
        <InputFilter />
        <ProductList collection={products} />
      </div>
    );
  }
}
```

In this example, the `ProductList` shows a list of products. Our goal is to filter this list with our `InputFilter` component based on user input. The problem here is that we have to communicate to `ProductList` what the user has typed. To do so, we will store the user input in the state of our `App`. By doing this, we are lifting the state of our `InputFilter` up into `App` to be able to share the data and pass it as props in our `ProductList`.

To do so, we will:

* Add a `userInput` state to our `App`.
* Initialize the default state
* Add a callback function that we will pass as props to `InputFilter`&#x20;

```jsx
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userInput: ''
    }
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    this.setState({
      userInput: event.target.value
    })
  }

  render() {
    return (
      <div>
        <InputFilter onChange={this.handleChange}>
        <ProductList collection={products} />
      </div>
    );
  }
}

function InputFilter(props) {
  return (
    <input type="text" onChange={props.onChange}>
  );
}
```

Every time a user types something in our `InputFilter`, the component will trigger the callback and will update the state of our parent.

Now that we store the user input in our `App`, we are able to pass this information to our `ProductList` component as a prop or even better, pass a filtered collection..

```jsx
class App extends React.Component {
  ...
  render() {
    const filteredProducts = filterProductByName(products, this.state.userInput)
    return (
      <div>
        <InputFilter onChange={this.handleChange}>
        <ProductList collection={filteredProducts} />
      </div>
    );
  }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shopify-1.gitbook.io/react/2.-intermediate/lifting-state-up.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
