manage state values
// Declare a new state variable, which we'll call "count".
const [count, setCount] = useState(0);
The Effect Hook lets you perform side effects in function components
// 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 ascomponentDidMount
,componentDidUpdate
, andcomponentWillUnmount
combined.
- 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:
function App() {
const inputElement = useRef();
const focusInput = () => {
inputElement.current.focus();
};
return (
<>
<input type="text" ref={inputElement} />
<button onClick={focusInput}>Focus Input</button>
</>
);
}
-
always RETURS A STATE VALUE
-
The
useReducer
Hook is similar to theuseState
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
- actions.js
export const SET_LOADING = 'SET_LOADING'
- action.type all UPPPER
SET_LOADING
- extra att placed inside payload
- actions.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)
}
- 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)
//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 }
//index.js
import { AppProvider } from './context'
ReactDOM.render(
<React.StrictMode>
<AppProvider>
<App /> //children
</AppProvider>
</React.StrictMode>,
document.getElementById('root')
)
// component.js
import { useGlobalContext } from './context'
...
const { removeStory } = useGlobalContext()
...
<button className="remove-btn" onClick={() => removeStory(objectID)}>
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
A tool that allows you to handle routes in a web app, using dynamic routing
//index.js
import { BrowserRouter as Router } from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<AppProvider>
<Router><App /></Router>
</AppProvider>
</React.StrictMode>,
document.getElementById('root')
)
//app.js
import { Routes, Route,} from "react-router-dom";
return (
<Routes>
<Route path='/' element={<Home />}>
<Route path='movies/:id' element={<Movie />} />
</Route>
</Routes>
)
import { Link } from "react-router-dom";
//component.js
<Link to="/">Home</Link>
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> );}
- Using
memo
will cause React to skip rendering a component if its props have not changed. - This can improve performance.
const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});
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
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
-
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.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);