16.8版本函数组件提供—-主要用于context传值。
接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 ` 的value` prop 决定。
在class组件中使用context传值
class App extends Component{
//组件中使用
this.context 获取传值
}
//静态字段 关联绑定context对象
App.contextType=myContext;
//函数组件中没有this指向 不能this.context获取
//版本迭代之后使用useContext来关联context对象到函数组件
在函数组件中使用context传值:
const value = useContext(MyContext);
案例中函数组件中使用useContext
//引入context对象
import { useContext } from "react";
import { MyContext } from "../components/context";
export default () => {
//使用useContext
let { menu } = useContext(MyContext);
return (
<>
<div style={
{ backgroundColor: menu.bgColor, color: menu.color }}>
menu
</div>
</>
);
};
以项目框架主题切换使用useContext。
useMemo
计算属性
把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。
参数:函数和依赖项数组
执行过程
import { useMemo } from "react";
export default () => {
//存在依赖进行计算
let value = useMemo(() => {
console.log("计算");
}, []);
console.log("渲染");
return (
<>
<div>测试</div>
</>
);
};
//先执行正常代码 useMemo 在渲染编译
let value = useMemo(() => {
console.log("计算");
});
let value = useMemo(() => {
console.log("计算");
}, [num]);
//useMemo依赖向可以写[] 或者 不写 或者写依赖项 首次默认执行 因为获取首次计算值
当useMemo的依赖项发生变化 useMemo重新运算
export default () => {
let [num, setNum] = useState(0);
//存在依赖进行计算
let value = useMemo(() => {
console.log("计算");
}, [num]);
console.log("渲染");
return (
<>
<button
onClick={() => {
setNum(1);
}}
>
修改
</button>
<div>测试</div>
</>
);
};
//useMemo只有依赖项更新时才重新运算
依赖项变化 useMemo 执行之后返回计算结果给useMemo返回值
//存在依赖进行计算
let value = useMemo(() => {
console.log("计算");
//逻辑运算 返回运算结果
return num * 10;
}, [num]);
useMemo可以依赖多个项
//存在依赖进行计算
let value = useMemo(() => {
console.log("计算");
//逻辑运算 返回运算结果
return (num + nums) * 10;
}, [num, nums]);
备注:
useMemo不写第二个参数:
首次默认执行运算,当前组件没更新一次都会执行,
useMemo第二个参数写[]:首次编译执行一次,后续更新不执行。
useMemo第二个参数存在依赖项: 首次都执行,只要依赖项更新useMemo重新运算。
useCallback
用法:const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
类似useMemo 都是计算
usecallback是返回的是内部的函数体。 使用时 执行该函数就是计算值。
把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。
使用useMemo返回函数体
//动态计算代办的总数
let count = useMemo(() => {
return function () {
return todoList.length;
};
}, [todoList]);
count();
//usecallback
let count = useCallback(
function () {
return todoList.length;
},
[todoList]
);
console.log(count);
useRef
创建获取dom元素节点。
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
createRef 类 函数
在函数组件中使用
import {createRef } from "react";
//创建节点对象
//定义节点对象
let trEle = createRef(null);
//关联到dom
<tr key={index} ref={trEle}>
useRef 函数
import { useRef } from "react";
//定义节点对象
//定义节点对象
let trEle = useRef(null);
//节点关联
<tr key={index} ref={trEle}>
父组件中操作ref获取子组件
//子组件为函数组件
<Page ref={pageEle}></Page>
//函数组件不是组件的实例
React.forwardRef() ref获取函数子组件需要进行ref转发。
如何转发:
import { forwardRef } from "react";
//props 为转发的函数组件props
// ref 为转发的子组件的ref
//forwardRef 参数为整个函数组件
let Page = forwardRef((props, ref) => {
console.log(props, ref);
return (
<>
<div ref={ref}>分页组件</div>
</>
);
});
export default Page;
//子组件
<Page ref={pageEle}></Page>
//ref获取函数子组件 直接获取不了需要ref转发
//等价直接获取函数组件的标签。
ref获取类子组件
<Pages ref={pagesEle}></Pages>
//直接给类组件关联 获取
类组件实例
如果同一个ref绑定多个元素
<Page ref={pageEle}></Page>
<button ref={pageEle}>按钮</button>
<button ref={pageEle}>按钮</button>
<p ref={pageEle}>1111</p>
//ref获取的是最后一个。