---
# System prepended metadata

title: React Notes
tags: [Web Technology, App, JavaScript, GUI, React]

---

# React Notes
###### tags: `React` `JavaScript` `GUI` `App` `Web Technology`

![](https://hackmd.io/_uploads/B1jELct-p.png)

Learn React as a beginner with JavaScript development experience.

ref:
- [從 JavaScript 到 React - Next.js](https://hackmd.io/@shibarashinu/HyLUtS173)
- [Learn React - React.dev](https://react.dev/learn/describing-the-ui)
- [React Hooks - w3schools](https://www.w3schools.com/react/react_hooks.asp)
- [30 Days Of React - github](https://github.com/Asabeneh/30-Days-Of-React)

impl tutorial:
- [Build and Deploy an Amazing 3D Web Developer Portfolio in React JS | Beginner Three.js Tutorial - JavaScript Mastery](https://www.youtube.com/watch?v=0fYi8SGA20k)
- [Build and Deploy a React Native App | 2023 React Native Course Tutorial for Beginners - JavaScript Mastery](https://www.youtube.com/watch?v=mJ3bGvy0WAY)
- [Build and Deploy a React Admin Dashboard App - JavaScript Mastery](https://www.youtube.com/watch?v=jx5hdo50a2M)

### Using React Scenario

The React framework is a library that manipulates UI components, creating a logical, MVC encapsulation module. And it also take advantage of optimizing the DOM tree lifetime updates and the rendering processes.

### Basic usage

1. use React library & JSX compiler (Babel)

```jsx=
// React library
<script src="/js/react-core.js"></script>
<script src="/js/react-dom.js"></script>

// Babel (for compiling following JSX)
<script src="/js/babel.js"></script>

<script type="text/jsx">
    const app = document.getElementById("app");
    ReactDOM.render(<h1>Hello</h1>, app);
</script>
```

2. JSX syntax
```jsx=
<script type="text/jsx">
    function MyComponent() {
        return (
        <div class="component">
            <MyContainer objItem="i" objItem2="i2" />
            <MyContainer objItem="ii" arr={ [ "li0", "li1" ] } />
        </div>
        );
    }
    function MyContainer({ objItem, objItem2, arr }) {
        return (
            <div class={ `${objItem}-my-container` }>  // class="i-my-container"
                { objItem2 || "default" }  // "i2": { ... } JSX syntax escape characters to javascript
            </div>
            <div>
            {arr.map((item) => (
                <li key={item.id}>{ item }</li>  // key: React "id" to identify different components
            ))}
            </div>
        );
    }
    
    const app = document.getElementById("app");
    ReactDOM.render(<div><MyComponent /></div>, app);
</script>

```

3. DOM event listener
```jsx=
function Banner() {
  function homeClick() {
    window.location = "/";
  }

  return (
    <div>
      <a onClick={homeClick}>Home</a>
    </div>
  );
}
```

4. useState (for every Component)
```jsx=
import { useState } from 'react';

function HomePage() {
    const [ storeValue, setValue ] = React.useState("init value");
    const [ value2, setValue2 ] = React.useState("init value2");

    return (
        <a onClick={ ()=>setValue("clicked") }>{ storeValue }</a>
    );
}

```

5. useRef (1. no new rendering process triggered compared to useState / 2. ref hook to get dom element)
```jsx=
import { useRef } from 'react';

function SendButton() {
    const ref = useRef("init");
    
    return (
        <button onClick={
            ()=>{
                ref.current = ref.current && "send";
            } }
        />
    );
}
```

```jsx=
import { useRef } from 'react';

function App() {
    const componentRef = useRef("init");
    
    useEffect(()=> {
        if(!!componentRef.currect)
            console.log(componentRef);
    })
    
    return (
        <Component ref={componentRef} />
    );
}
```

6. useReducer (states transition: initial => case dispatch => new state)

[A cure for React useState hell - Steve (Builder.io)](https://www.youtube.com/watch?v=sGdW4Amolq4&ab_channel=Steve%28Builder.io%29)
```jsx=
const dispatcher = {
    add: (state) => { count: state.count + 1 },  // return blend new obj as new state instead of modified state
    sub: (state) => { count: state.count - 1 }
}

function reducer(state, action) {
    const dispatchFunc = dispatcher[action.type];
    return dispatchFunc ? dispatchFunc(state) : state;
}

const Buttons = () => {
	const [state, dispatch] = useReducer(reducer, { count: 0 });
	const addClick = () => { dispatch({ type: "add" }) };
	const subClick = () => { dispatch({ type: "sub" }) };
 
    return (
    <div> 
    	<button onClick={ addClick } />
    	<button onClick={ subClick } />
    </div>);
};
```

7. useContext (for interior-cross var get / set within Component block)
```jsx=
// Context-definition-lib.js
import { createContext } from 'react';

export const MyLayerContext = createContext({
    level: 0,
    name: "root",
    state, setState
});
```
```jsx=
// Component.js
import { useState, useContext } from 'react'
import { MyLayerContext } from './Context-definition-lib.js'

export default function Section({ children }) {
    const [state, setState] = useState("initial");
    const parentLayerContext = useContext(MyLayerContext);
    return (
        <section>
            <div>{ name + '-' + layer }</div>
            <MyLayerContext.Provider
                value={{
                    layer: parentLayerContext.layer + 1,
                    name: "section",
                    state, setState // so children can get / set parent provider's state
                }}
            >
                { children }
            </MyLayerContext.Provider>
        </section>
    );
}
```

8. useEffect (== Component drawcall)
:::warning
**Virtual DOM Management**

If a virtual DOM's element is unmounted, React bottom-up cleans up the corresponding subtree, that is:
1. remove the element from the actual DOM tree.
2. remove internal references, corresponding resources & invoke their cleanup callbacks, so to prevent memory leaks.
:::

```jsx=
import { useState, useEffect } from 'react'

function Timer() {
    const [state, setState] = useState(0);

    useEffect(() => {
        setTimeout(() => {
            setState((origin) => origin + 1);
        }, 1000);
        
        const cleanupFunc = () => { db.disconnect(); };
        return cleanupFunc;
    }, [state, state2]);  // <- render if any dependency value changes

    return <div>state: {state}</div>;
}
```

(8-2. useLayoutEffect (sync drawcall))

9. useCallback (call this Component to render if the observed variables have changed)
```jsx=
const Arr = ({ arr, insert }) => {
  return (
    <>
      <h2>My Array</h2>
      { arr.map((item, ind) => (<p key={index}>{todo}</p>)) }
      <button onClick={ insert }>Add Item</button>
    </>
  );
};

const App = () => {
  const [arr, setArr] = useState([]);

  const insert = useCallback(() => {
    setArr((arr) => [...arr, "new item"]);
  }, [arr]);

  return <Arr arr={arr} insert={insert} />;
};
```

10. useMemo (same as useCallback but use it as a React component)
> [useMemo vs. useEffect + useState - StackOverflow](https://stackoverflow.com/questions/56028913/usememo-vs-useeffect-usestate)
> The `useEffect` and `setState` will cause extra renders on every change: the first render will "lag behind" with stale data and then it'll immediately queue up an additional render with the new data.
> ```jsx=
> function expensiveCalculation(x) { return x + 1; };
> ```
> Lets suppose x is initially 0:
> - The `useMemo` version immediately renders 1.
> - The `useEffect` version renders null, then after the component renders the effect runs, changes the state, and queues up a new render with 1.
> 
> Then if we change x to 2:
> - The `useMemo` runs and 3 is rendered.
> - The `useEffect` version runs, and renders 1 again, then the effect triggers and the component reruns with the correct value of 3.

```jsx=
const App = () => {
    const [count, setCount] = useState(0);
    const result = useMemo(() => expensiveCalculation(count), [count]);

    const increment = () => {
        setCount((count) => count + 1);
    };

    return (
        <div>
        Count: {count}
        <button onClick={increment}>+</button>
        <h2>Expensive Calculation</h2>
        {result}
        </div>
    );
};

const expensiveCalculation = (num) => {
    for (let i = 0; i < 1000000000; i++) {
        num++;
    }
    return num;
};
```

11. useQuery (auto fetch when var changed)
```jsx=
const result = useQuery("/api/books", { var });
```

100. my custom use hook
```jsx=
const myUseFetch = (url) => {
  const [data, setData] = useState(null);  // ! concatenate the React useState hook

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(data => setData(data));
  }, [url]);

  return [data];
};

export default myUseFetch;
```