Skip to content

Instantly share code, notes, and snippets.

@abdelghanyMh
Created May 23, 2022 11:16
Show Gist options
  • Select an option

  • Save abdelghanyMh/511bc61fa7432ae845f334a0a48c37a7 to your computer and use it in GitHub Desktop.

Select an option

Save abdelghanyMh/511bc61fa7432ae845f334a0a48c37a7 to your computer and use it in GitHub Desktop.

Revisions

  1. abdelghanyMh created this gist May 23, 2022.
    238 changes: 238 additions & 0 deletions React Hooks.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,238 @@
    # React Hooks

    * [useState](#usestate)
    * [useEffect](#useeffect)
    * [useRef](#useref)
    * [useReducer](#usereducer)
    * [useContext](#usecontext)
    * [React Router](#react-router)
    * [React.memo](#react.memo)
    * [useCallback](#usecallback)
    * [useMemo](#usememo)


    # 1. useState
    manage state values
    ```js
    // Declare a new state variable, which we'll call "count".
    const [count, setCount] = useState(0);
    ```
    # 2. useEffect
    The _Effect Hook_ lets you perform side effects in function components
    ```js
    // Similar to componentDidMount and componentDidUpdate:
    useEffect(()=>{},[dependencies,Array ])

    useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
    });
    ```
    >If you’re familiar with React class lifecycle methods, you can think of `useEffect` Hook as `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount` combined.
    # 3. useRef
    - The `useRef` Hook allows you to persist values between renders.
    - It can be used to store a mutable value that does not cause a re-render when updated.
    - It can be used to access a DOM element directly.
    > Use `useRef` to focus the input:
    ```jsx
    function App() {
    const inputElement = useRef();

    const focusInput = () => {
    inputElement.current.focus();
    };

    return (
    <>
    <input type="text" ref={inputElement} />
    <button onClick={focusInput}>Focus Input</button>
    </>
    );
    }

    ```
    # 4. useReducer

    - always **RETURS A STATE VALUE**
    - The `useReducer` Hook is similar to the `useState` Hook.
    - It allows for custom state logic.

    - If you find yourself keeping track of multiple pieces of state that rely on complex logic, `useReducer` may be useful.
    - best practices
    1. actions.js `export const SET_LOADING = 'SET_LOADING' `
    2. action.type all UPPPER `SET_LOADING `
    3. extra att placed inside payload
    ```js
    //context.js
    const [state, dispatch] = useReducer(reducer, initialState)

    const removeStory = (id) => {dispatch({ type: REMOVE_STORY, payload: id })}

    // reducer.js
    case REMOVE_STORY:
    return {...state, hits: state.hits.filter(story => story.objectID !== action.payload)
    }
    ```
    # 5. useContext
    - React Context is a way to manage state globally.
    - Prevent props drilling (passing props to lower-level component that doesn't use them but there children does)
    ```js
    //context.js
    import React, { useContext } from 'react'

    const AppContext = React.createContext()

    const AppProvider = ({ children }) => {

    const [state, dispatch] = useReducer(reducer, initialState)


    const removeStory = (id) => {

    dispatch({ type: REMOVE_STORY, payload: id })

    }


    return <AppContext.Provider value={{...state,removeStory,handleSearch,handlePAge}}>{children}</AppContext.Provider>
    }
    // make sure use
    export const useGlobalContext = () => {
    return useContext(AppContext)
    }
    export { AppContext, AppProvider }
    ```

    ```js
    //index.js

    import { AppProvider } from './context'

    ReactDOM.render(
    <React.StrictMode>

    <AppProvider>
    <App /> //children
    </AppProvider>

    </React.StrictMode>,
    document.getElementById('root')
    )
    ```
    ``` js
    // component.js
    import { useGlobalContext } from './context'
    ...

    const { removeStory } = useGlobalContext()

    ...

    <button className="remove-btn" onClick={() => removeStory(objectID)}>

    ```

    ```mermaid
    graph LR
    A((btn-clicked))--removeStory objectID-->B
    B((CONTEXT.js))-- dispatch type: REMOVE_STORY payload: id -->C((reducer.js))
    C--UPDATE THE STATE-->B
    ```

    # 6. React Router
    A tool that allows you to handle routes in a web app, using dynamic routing

    ### configuring-routes
    ```js
    //index.js
    import { BrowserRouter as Router } from 'react-router-dom'

    ReactDOM.render(
    <React.StrictMode>
    <AppProvider>

    <Router><App /></Router>

    </AppProvider>
    </React.StrictMode>,
    document.getElementById('root')
    )

    ```

    ```js
    //app.js
    import { Routes, Route,} from "react-router-dom";

    return (

    <Routes>
    <Route path='/' element={<Home />}>
    <Route path='movies/:id' element={<Movie />} />
    </Route>
    </Routes>
    )

    ```
    ### Navigation


    ```js
    import { Link } from "react-router-dom";
    //component.js
    <Link to="/">Home</Link>
    ```

    ```js
    import { useNavigate } from "react-router-dom";
    //component.js

    function Invoices() {
    let navigate = useNavigate();
    return (
    <div>
    <NewInvoiceForm
    onSubmit={async (event) => {
    let newInvoice = await createInvoice(
    event.target
    );
    navigate(`/invoices/${newInvoice.id}`);
    }}
    />
    </div> );}
    ```

    # 7. React.memo
    - Using `memo` will cause React to skip rendering a component if its props have not changed.
    - This can improve performance.
    ```js
    const MyComponent = React.memo(function MyComponent(props) {
    /* render using props */
    });
    ```
    # 8. useCallback
    - `useCallback` will return a memoized version of the callback that only changes if one of the dependencies has changed.
    - This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders
    - **Re-render function only if the value of one of the dependencies has changed.**
    - The dependencies array is mandatory since each change requires re-creating the function, otherwise, the function will only be invoked once
    ```js
    const memoizedCallback = useCallback(
    () => {
    doSomething(a, b);
    },
    [a, b],
    );
    ```


    # 9. useMemo

    - The React `useMemo` Hook returns a memoized value.
    - Think of memoization as caching a value so that it does not need to be recalculated.
    - The `useMemo` Hook only runs when one of its dependencies update.

    - so you have value need to calculated each time and its takes time for the calculation to be done to prevent react from doing the calculation each time we use useMemo to do the calculation when one of its dependencies update.
    ```js
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
    ```