Hooks allows you to have state, hook into lifecycle, share functionality
Started from very arguable, now almost the standard
React relays on the order of hook invocations
const App = () => {
const [state, setCounter] = useState(0);
return (
<button onClick={() => setCounter(state + 1)}>
Increment: {state}
</button>
);
};
const WrongApp = () => {
const [state, setState] = useState({ isAdmin: false });
const assignAdmin = () => {
state.isAdmin = true; // WRONG
setState(state);
};
return <button onClick={assignAdmin}>Assign admin</button>;
};
const WrongApp = () => {
const [state, setState] = useState({ isAdmin: false });
const assignAdmin = () => {
setState({ ...state, isAdmin: true }); // CORRECT
};
return <button onClick={assignAdmin}>Assign admin</button>;
};
Debugging, logging or measuring
useEffect(() => console.log("component invoked"));
Calls to the server, initialization
//note second argument
useEffect(()=> {console.log('one time action')}, []);
Recall when the value changed
useEffect(() => console.log("component invoked"), [dependency]);
Cleanup the resources like timers or pending requests
useEffect(() => {
... // logic
return ()=> console.log('cleaning ...');
});
import { createContext } from "react";
const defaultValue = { name: "Vitalii", isAdmin: true };
const UserCtx = createContext(defaultValue);
const App = () => {
return (
<UserCtx.Provider value={defaultValue}>
<h1>This is my app</h1>
<AboutUser />
</UserCtx.Provider>
);
};
const AboutUser = () => {
const { name, isAdmin } = useContext(UserCtx);
return (
<div>
UserName: {name}, isAdmin: {isAdmin}
</div>
);
};
type WithCallback = { callback: () => void };
class ExpensiveComponent extends PureComponent<WithCallback> {
render() { return <div>Expensive</div>; }
componentDidUpdate() { console.log("updated"); }
}
const App = () => {
const [state, setState] = useState(0);
const callback = ()=> {};
return (
<>
<ExpensiveComponent callback={callback} />
<button onClick={() => setState(state + 1)}>
Increment: {state}
</button>
</>
);
};
const callback = useCallback(() => {}, []);
const useCounter = (defaultValue: number) => {
const [state, setState] = useState(defaultValue);
const increment = useCallback(
() => setState(state + 1),
[state]);
return { state, increment };
};
const App = () => {
const { state, increment } = useCounter(0);
return (
<button onClick={increment}>Increment: {state}</button>
);
};