[React] Lifting state up
Published: 2023-06-26 15:49:38

[Lifting state up](https://react.dev/learn/sharing-state-between-components#lifting-state-up-by-example)

## React Data flow: Top-down
- One-way data flow
- Subject that delivers data: parent component
- The child component can only know the form/type of the data received from the upper component
- It does not know whether the data came from the state or was hard-coded.

<br/>

## How to develop with React
Dividing into components rather than page units

### 1. Divide your app's prototype into component hierarchies 
- **Single Responsibility Principle**
: One component can only do one thing

**[e.g.]Twittler**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1n3pd5c7pe3oanvev4zb.png)

- SingleTweet : Each Tweet posted by a user
- Tweets : set of Tweets
- NewTweetForm : Where to write new tweets
- Twittler : Container that holds all components


<br/>

### 2. Bottom-up Design
- easy testing, scalability
- Represent it as a tree structure
![](https://velog.velcdn.com/images/kdhwh09/post/c28b4558-5cea-45ad-8d8f-35a536cd0c9f/image.png)


<br/>

### 3. What value should be used as the state? 

**Values that change vs Values that do not change**
**[These values can be state...]**
- It's not transmitted via props from the parent
- Its value changes over time
- It's not possible to be computed with other state and props inside the component

**[States in the application]**
- New tweets created by users
- List of tweets (can be changed by adding new tweets)

<br/>


### 4. Where to put the state
- If it's meaningful only in a specific component, it can be located in the specific component
- If multiple components are affected based on one state, then you need to find the parent component that owns the components and place the state there.
- When two child components need accesss to one state, state should be placed in common parent component of both children

<br/>

### 5. Lifting state up
- Reverse Data flow
: An event in a child component causes the state of the parent component to change
- This seems to violate the principle of top-down unidirectional data flow in React.



#### What is the solution that conforms to React's one-way data flow (top-down) principle?

#### [Lifting state up]
- Pass a function that changes the state of the parent component to the child component
- The child component executes this function

- This solution conforms to the principle of unidirectional data flow. 


[e.g]
▶️ **New tweet being written by users**

- Other components are not affected by the user's input
- No need to share the state with other components
- Locate the state in NewTweetForm

▶️ **Event to add a new post**
- Add a new tweet object to the list of all tweets
- When a new post is added, the status of Tweets also changes
- The entire tweet list state should be placed in the common parent component of both components (Twittler)

<br/>

## Use a Callback function
- Callback: Functions passed as arguments to other functions (higher-order functions)
- When passing a function that changes the parent component’s state value to a child component, use a callback function! 

[e.g. Callback]
```javascript
function each(array,iterator) {
  for(let i=0;i<arr.length;i++){
    let element=array[i]
    iterator(element,i,array)
  }
}

function printElement(element) {
  console.log(element)
}

each(['hello','world'],printElement);
```



[e.g. Lifting state up]
```jsx
import React, { useState } from "react";

export default function ParentComponent() {
  const [value, setValue] = useState("initial value");

  const handleChangeValue = () => {
    setValue("Changed Value");
  };

  return (
    <div>
      <div>Value is {value}</div>
      <ChildComponent handleButtonClick={handleChangeValue} />
    </div>
  );
}

function ChildComponent({handleButtonClick}) {
  const handleClick = () => {
    handlieButtonClick()
  };

  return <button onClick={handleClick}>Change the Value!</button>;
}
```