react中的useRef和useContext
1. useRef可以进行状态管理和获取DOM节点
1-1状态管理
useRef和useState类似,都可以用来保存数据状态,但是useRef更新数据是同步的,且不会触发视图更新。
useRef返回一个对象,初始化数据保存在current字段下
import {useRef} from 'react'; const data = useRef(0); const obj = useRef({a: 1, b:1}); console.log(data); // {current:0} console.log(obj); // {current:{a: 1, b: 1}} // 更新数据 data.current = 1; obj.current = {...obj.current,b:2}; console.log(data); // {current:1} console.log(obj); // {current:{a: 1, b: 2}}
当useRef和useState一起使用的话,useState会触发视图更新,这时useRef更新的数据也会被一起重新渲染!
import { useRef, useState } from 'react';
const count = useRef(0); const add = () => { count.current++; // useRef更新数据不会触发视图更新 } return ( <div onClick={add}}>{count.current}</div> // 0,不会更新成新数据 ) ... const count = useRef(0); const [data,setData] = useState(0); const add = () => { count.current++; setData(22); // useState更新数据触发视图更新 } return ( <div onClick={add}}>{count.current}</div> // 1,重新渲染成新数据 )
1-2 获取DOM节点
import {useEffect, useRef} from 'react'; function App(){ const myDom = useRef(); useEffect(()=>{ console.log(myDom); // 绑定的DOM节点 },[]) return ( <div ref={myDom}>111</div> ) }
2. useContext用来实现子组件之间数据共享,共享的数据通过value属性传入子组件
import React,{useContext} from 'react'; const contextMsg = React.createContext(); function Father(){ const [count,setCount] = useSate(0) return ( <contextMsg.Provider value={{count,setCount}}> <Child1 /> <Child2 /> </contextMsg.Provider> ) } function child1(){ const {count,setCount} = useContext(contextMsg); // 注意useContext传入的参数是它本身 useEffect(()=>{ console.log(count); // 0 },[]) const add = ()=>{ setCount(count+1); // 所有引用count的地方数据会同步更新到视图 } return ( <div onClick={add}>{count}</div> ) } function child2(){ const {count,setCount} = useContext(contextMsg); // 注意useContext传入的参数是它本身 useEffect(()=>{ console.log(count); // 0 },[]) const add = ()=>{ setCount(count+1); // 所有引用count的地方数据会同步更新到视图 } return ( <div onClick={add}>{count}</div> ) }
通常我们可以新建一个context.js文件用来创建需要共享的数据
context.js
import React from 'react';
export const contextMsg = React.createContext();
在父组件以及共享数据的子组件里面需要用到的时候引入
Father.js
import {contextMsg} from '.../context.js'; function Father(){ const [count,setCount] = useSate(0) return ( <contextMsg.Provider value={{count,setCount}}> <Child1 /> <Child2 /> </contextMsg.Provider> ) } export defalut Father;
Child1.js
import {contextMsg} from '../context.js'; function Child1(){ const {count,setCount} = useContext(contextMsg); // 注意useContext传入的参数是它本身 useEffect(()=>{ console.log(count); // 0 },[]) const add = ()=>{ setCount(count+1); // 所有引用count的地方数据会同步更新到视图 } return ( <div onClick={add}>{count}</div> ) }
export default Child1