import React, {useEffect} from 'react';
- for side effect like data fetching, or anything should be done in
componentDidMount()
orcomponentDidUpdate()
- to mimic
componentDidMount()
, provide a empty array as deps array more
useEffect(() =>{
console.log("mounted")
}, []);
- remember to return a callback function to do cleanup, especially the effect function called subscription to avoid no-op (also work as
componentDidUnmount()
- create a accessable & mutable
ref
for parent - instance variable replacement [ref]
- Pros: useRef will give you the same ref object on every render
- Cons:
- useRef doesn’t notify you when its content changes.
- Mutating the .current property doesn’t cause a re-render.
- "If you want to run some code when React attaches or detaches a ref to a node, you may want to use a callback ref instead." (doc)
- use to expose instance variables and methods for the ref exposed by
useRef()
:
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} {...props} />;
}
FancyInput = forwardRef(FancyInput); //react-dom
// On parent side
let inputRef;
button = <FancyInput ref={inputRef} />
inputRef.current.focus()
- cloud be class member and member function replacement?
- avoid unneccessary re-computation by re-rendering by memorization
- 'create' callback function must return a value (any)
- can return react component
- caution: if no deps array is provided, a new value will be computed on every render
- caution: function as deps deprecedated. some reference code is no longer working example
- useCallback(fn, deps) is equivalent to useMemo(() => fn, deps)
- This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
intro: link
further reading: link
- replacement of
this.state
- make good use of the first arg: if this is a function, this is the initializer
- note: useState does not automatically merge update objects, if the object structure is deep, use
useReducer()
[ref]
- same as redux reducer
- will cause less re-rendering
- the Context Provider/Consumer API without wrapping a consumer:
- Have a Context to store data
- Have a to bind the Context to the
- Consumer component call useContext to access the context
- Can replace redux store or provide global variable/subscription hub
Any class or pure function will cause eror
- deps array is used to include the variable which will trigger recomputation when they changes
- changes detection is done by
Object.is()
(basic heuristic) - but that variable can be comparator's result
useEffect(
() => {
// ...
},
[compare(a, b)]
);
[source]
aka. "Send data from child to parent component" (Lift up)
The idea:
"When the child called setState(newState)
, do a callback (cb(newState)
), or, dispatch(newState)
"
- dispatcher
dispatch(newState)
can be any reducer fromuseReducer()
oruseRedux()
- dispatcher pass by props from parent, so child have minimial knowledge to parent
anther alternative:
- useContext()
- useRef + useImperativeHandle() (The DOM way)
Reference