原文链接: react hook useContext 透传状态
上一篇: 状态同步和帧同步
下一篇: react hook 依赖诚实和依赖欺骗
参考
http://www.ptbird.cn/react-createContex-useContext.html
通常使用useContext透传数据, 不过大部分时候当你需要用useContext的时候, 你真正需要的是redux
普通对象, 值的变化不会被react追踪和响应ui变化
可以看到数值确实变化了, 但是ui并没有响应变化和捕捉到, 也不会触发useEffect
import React, { useContext } from "react";
import { useEffect } from "react";
const defaultConext = {
count: 0,
inc: () => defaultConext.count++,
dec: () => defaultConext.count--,
};
const context = React.createContext(defaultConext);
const A = (props) => {
const { count, inc, dec } = useContext(context);
return (
A:{count}
);
};
const B = () => {
const { count, inc, dec } = useContext(context);
useEffect(() => {
console.log("B", count);
}, [count]);
return (
);
};
const C = () => {
const { count, inc, dec } = useContext(context);
console.log("count", count, inc, dec, defaultConext);
return (
C:{count}
;
);
};
export default C;
使用hook, 此时可以捕捉并引起UI变化
import React, { useContext } from "react";
import { useEffect } from "react";
import { useState } from "react";
const context = React.createContext(null);
const A = (props) => {
const { count, inc, dec } = useContext(context);
return (
A:{count}
);
};
const B = () => {
const { count, inc, dec } = useContext(context);
useEffect(() => {
console.log("B", count);
}, [count]);
return (
);
};
const C = () => {
const [count, setCount] = useState(0);
const inc = () => setCount((i) => i + 1);
const dec = () => setCount((i) => i - 1);
const value = { count, inc, dec };
return (
C:{count}
;
);
};
export default C;
性能问题, 父组件中修改了子组件没用过的值, 也会触发子组件渲染, 可以使用reducer和memo解决, 但是这么搞真不如接入redux
import React, { useContext } from "react";
import { useEffect } from "react";
import { useState } from "react";
const context = React.createContext(null);
const A = (props) => {
const { count, inc, dec } = useContext(context);
return (
A:{count}
);
};
const B = () => {
const { count, inc, dec } = useContext(context);
useEffect(() => {
console.log("B", count);
}, [count]);
console.log("B re");
return (
);
};
const C = () => {
const [count, setCount] = useState(0);
const [count2, setCount2] = useState(0);
const inc = () => setCount((i) => i + 1);
const dec = () => setCount((i) => i - 1);
const value = { count, inc, dec };
return (
C:{count},{count2}
;
);
};
export default C;
可以使用useCallback和useMemo 优化, 尽量避免重新渲染组件, 需改count2, b不会进入到memo函数中, 修改count1才会重新计算memo
输出两次是因为开发模式, build后就只有一次了
build
dev
import React, { useContext, useCallback, useMemo } from "react";
import { useEffect } from "react";
import { useState } from "react";
const context = React.createContext(null);
const A = (props) => {
const { count, inc, dec } = useContext(context);
return (
A:{count}
);
};
const B = () => {
const { count, inc, dec } = useContext(context);
useEffect(() => {
console.log("B", count);
}, [count]);
console.log("B re", count);
return useMemo(() => {
console.log("b return", count);
return (
);
}, [count]);
};
const C = () => {
const [count, setCount] = useState(0);
const [count2, setCount2] = useState(0);
const inc = useCallback(() => setCount((i) => i + 1), [setCount]);
const dec = useCallback(() => setCount((i) => i - 1), [setCount]);
const value = useMemo(() => ({ count, inc, dec }), [count, inc, dec]);
return (
C:{count},{count2}
;
);
};
export default C;