---
# System prepended metadata

title: React Project From Scratch
tags: [react]

---

# React Project From Scratch

###### tags: `react`

## [Think in React](https://reactjs.org/docs/thinking-in-react.html)

### Step 1: Break The UI Into A Component Hierarchy

<img src="https://reactjs.org/static/9381f09e609723a8bb6e4ba1a7713b46/90cbd/thinking-in-react-components.png">

You’ll see here that we have five components in our app. We’ve italicized the data each component represents. The numbers in the image correspond to the numbers below.

- FilterableProductTable (orange): contains the entirety of the example
- SearchBar (blue): receives all user input
- ProductTable (green): displays and filters the data collection based on user input
- ProductCategoryRow (turquoise): displays a heading for each category
- ProductRow (red): displays a row for each product

If you look at ProductTable, you’ll see that the table header (containing the “Name” and “Price” labels) isn’t its own component. This is a matter of preference, and there’s an argument to be made either way. For this example, we left it as part of ProductTable because it is part of rendering the data collection which is ProductTable’s responsibility. However, if this header grows to be complex (e.g., if we were to add affordances for sorting), it would certainly make sense to make this its own ProductTableHeader component.

Now that we’ve identified the components in our mock, let’s arrange them into a hierarchy. Components that appear within another component in the mock should appear as a child in the hierarchy:

- FilterableProductTable
    - SearchBar
    - ProductTable
        - ProductCategoryRow
        - ProductRow

### Step 2: Build A Static Version in React

- don’t use state at all to build this static version
    - State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don’t need it.
- The components will only have render() methods in this step

related article: [What is the difference between state and props?](https://reactjs.org/docs/faq-state.html#what-is-the-difference-between-state-and-props)

### Step 3: Identify The Minimal Representation Of UI State

Related article: [DRY: Don’t Repeat Yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)

**Principle:** if you’re building a TODO list, keep an array of the TODO items around; don’t keep a separate state variable for the count. Instead, when you want to render the TODO count, take the length of the TODO items array.

Which data is **state**?
- Is it passed in from a parent via props? If so, it probably isn’t state.
- Does it remain unchanged over time? If so, it probably isn’t state.
- Can you compute it based on any other state or props in your component? If so, it isn’t state.

### Step 4: Identify Where Your State Should Live

**Principle:** Find the nearest shared parent component to put the state.

## init project
```
npx create-react-app APP_NAME
```

then run 
```
npm start
# or
yarn start
```
so simple! right?

## Tools Good To Have

### install es7 extension
![](https://i.imgur.com/73wRLSp.png)

type "rfce", then BOOM! auto create template for you!
![](https://i.imgur.com/ks8gvwf.png)

### brower dev tool
[Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en)

<img src='https://zh-hant.reactjs.org/static/41330fe61a925e2c3009be675bdb96a9/f2205/devtools.png'>

## React Router
```
npm install react-router-dom

# deal with the Switch was replaced issue
npm uninstall react-router-dom
npm install react-router-dom@5.2.0
```

### intro
```javascript
// in index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom';
import App from './App';

// wrap your app with BrowserRouter
ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>
)
```

```javascript
// in App.js
import React from 'react';
import {Route} from 'react-router-dom';

funciton App() {
    return(
        // manage routes like this
        <div>
            <Route path='/'>
                <Home/>
            </Route>
            <Route path='/about'>
                <About/>
            </Route>
            <Route path='/products'>
                <Products/>
            </Route>
            <Route path='/works'>
                <Works/>
            </Route>
        </div>
    );
}
```

However, in this way, if we go to "/about", we will see both "Home", and "About" since by default it check if input url caontains "path".

To solve it, we introduce `<Switch>`
```javascript
// in App.js
import React from 'react';
import {Route} from 'react-router-dom';

funciton App() {
    return(
        // manage routes like this
        <div>
            <Switch>
                <Route path='/'>
                    <Home/>
                </Route>
                <Route path='/about'>
                    <About/>
                </Route>
                <Route path='/products'>
                    <Products/>
                </Route>
                <Route path='/works'>
                    <Works/>
                </Route>
            </Switch>
        </div>
    );
}
```
Now, if we go to "/products", we only see "Home"...
Since React Router match url START from the given path, and "/products" does start from "/", thus matched! return "Home"

To fix it, we need anther attribute, `exact`
```javascript
<Switch>
    <Route path='/' exact>
        <Home/>
    </Route>
    <Route path='/about'>
        <About/>
    </Route>
    <Route path='/products'>
        <Products/>
    </Route>
    <Route path='/works'>
        <Works/>
    </Route>
</Switch>
```

### <Link>
What `<Link>` does is like `<a>` tag but it doesn't really send a request. Instead, it updates the url at url-bar of our browser and loads the page we want without actaully send a request.

```javascript
<ul>
    <li>
        <Link to='/'>Home</Link>
    </li>
    <li>
        <Link to='/products'>products</Link>
    </li>
    <li>
        <Link to='/works'>works</Link>
    </li>
</ul>
```

## React incons

```
npm install react-icons --save
```

## sync, async, await, promise