| 特性 | plain variable | state | ref |
|---|---|---|---|
| 渲染后引用是否相同 | ❎ | ❎ | ✔ |
| 是否可以update | ❎ | ✔ | ✔ |
- useContext的变化会引起中间组件的重新渲染
- store的变化只会引起相关组件的重新渲染
- 持久化的引用,只有
current可用 - 可以用来获取或者添加
dom node
useMemo用来缓存昂贵计算的值, 也可以缓存组件useCallback用来持久化函数的引用memo用来缓存组件, 可以避免由父组件渲染引起的不必要的子组件渲染
- 创建context
- defaultContext是在没有provider的情况下,传给consumer或者useContext的默认值,但是是不可变的,无法通过setContext来变更。
// userContext.js import { createContext } from 'react'; const UserContext = createContext([ { firstName: 'Bob', lastName: 'Bobberson', suffix: 1, email: 'bobberson@example.com' }, obj => obj ]) const { Provider } = UserContext; export { Provider, UserContext }- 创建Provider
const UseContext = () => { // 这个才是人类理解的默认值,可通过setContext来变更 const user = useState({ firstName: 'James', lastName: 'Tan', suffix: 1, email: 'james@example.com' }) return ( <div> <Provider value={user}> <h1>1st level</h1> <Level2></Level2> </Provider> </div> // ) }- 创建Consumer
const Level5 = () => { // 接收context const [user, setUser] = useContext<any>(UserContext); return ( <div> <h5>{`${user.firstName} ${user.lastName} the ${user.suffix} born`}</h5> <button onClick={() => { setUser({ ...user, suffix: user.suffix + 1 }) }}>Increment</button> </div> ) }- 能够跟
useRef一起获得子组件的DOM - 在
父组件创建ref,传递到子组件, 在父组件获取DOM
const FancyButton = React.forwardRef((props, ref) => ( <button ref={ref} className="FancyButton"> {props.children} </button> )); // You can now get a ref directly to the DOM button: const ref = React.createRef(); <FancyButton ref={ref}>Click me!</FancyButton>;- 结合
useRef和forwardRef, 允许子组件将操作自身DOM的函数传递给父组件(向上传递)
htmlForforforContext+useReducer=Redux; 其实还是redux的方案更好,context其实只是props多层传递的一种简化而已。styled-component:emotion.sh将css复用粒度提升tag层面到了component层面,但是加快了开发速度,可以适用于小型项目。styled-component高亮插件:vscode-styled-componentsass:yarn add node-sasssetState: hooks是function之外的又一层,写在代码里的顺序,不一定是它真实的执行顺序
