Closed arealclimber closed 9 months ago
<number>
,b 改變會造成 com1, com2 渲染import React, {createContext, useEffect, useState} from 'react';
import useStateRef from 'react-usestateref';
interface ITestProvider {
children: React.ReactNode;
}
interface ITestContext {
a: number;
b: number;
}
export const TestContext = createContext<ITestContext>({
a: 0,
b: 0,
});
export const TestProvider = ({children}: ITestProvider) => {
const [a, setA, aRef] = useStateRef(1129);
const [b, setB, bRef] = useStateRef(956);
useEffect(() => {
const int = setInterval(() => {
const randNum = Math.floor(Math.random() * 1000);
setB(randNum);
// eslint-disable-next-line no-console
console.log('value in TestContext', a, b);
}, 3000);
return () => {
clearInterval(int);
};
}, []);
const defaultValue = {
a,
b,
};
return <TestContext.Provider value={defaultValue}>{children}</TestContext.Provider>;
};
import React, {useContext} from 'react';
import {TestContext, TestProvider} from '../contexts/test_context';
import TestComponent1 from '../components/test_component1';
import TestComponent2 from '../components/test_component2';
const Trial = () => {
return (
<>
<TestProvider>
<div className="flex flex-col">
<TestComponent1 /> <TestComponent2 />
</div>
</TestProvider>
</>
);
};
export default Trial;
import React, {useContext} from 'react';
import {TestContext} from '../contexts/test_context';
const TestComponent1 = ({val}: {val?: any}) => {
const testCtx = useContext(TestContext);
// eslint-disable-next-line no-console
console.log('testCtx in com 1', testCtx);
return <div>Component1: {val ? val : testCtx.a}</div>;
};
export default TestComponent1;
import React, {useContext} from 'react';
import {TestContext} from '../contexts/test_context';
const TestComponent2 = ({val}: {val?: any}) => {
const testCtx = useContext(TestContext);
// eslint-disable-next-line no-console
console.log('testCtx in com 2', testCtx);
return <div>Component2: {val ? val : testCtx.b}</div>;
};
export default TestComponent2;
import React, {createContext, useEffect, useMemo, useState} from 'react';
import useStateRef from 'react-usestateref';
interface ITestProvider {
children: React.ReactNode;
}
interface ITestContext {
a: number;
b: number;
}
export const TestContext = createContext<ITestContext>({
a: 0,
b: 0,
});
export const TestProvider = ({children}: ITestProvider) => {
// const [a, setA, aRef] = useStateRef(1129);
const [b, setB, bRef] = useStateRef(956);
const a = useMemo(() => {
return Math.floor(Math.random() * 1000);
}, []);
useEffect(() => {
const int = setInterval(() => {
const randNum = Math.floor(Math.random() * 1000);
setB(randNum);
// eslint-disable-next-line no-console
console.log('setInterval in TestContext', a, b);
}, 3000);
return () => {
clearInterval(int);
};
}, []);
const defaultValue = {
// a: aRef.current,
a,
b: bRef.current,
};
return <TestContext.Provider value={defaultValue}>{children}</TestContext.Provider>;
};
import React, {createContext, useEffect, useMemo, useState} from 'react';
import useStateRef from 'react-usestateref';
interface IA {
a1: string;
a2: number;
a3: {
a31: string;
a32: boolean;
};
}
interface ITestProvider {
children: React.ReactNode;
}
interface ITestContext {
a: IA;
b: number;
}
export const TestContext = createContext<ITestContext>({
a: {
a1: '',
a2: 0,
a3: {
a31: '',
a32: false,
},
},
b: 0,
});
export const TestProvider = ({children}: ITestProvider) => {
const [a, setA, aRef] = useStateRef({
a1: 'a1',
a2: 1,
a3: {
a31: 'a31',
a32: true,
},
});
const [b, setB, bRef] = useStateRef(956);
useEffect(() => {
const int = setInterval(() => {
// change a31 randomly
setA(prev => {
return {
...prev,
a3: {
...prev.a3,
a31: Math.random().toString(),
},
};
});
}, 3000);
return () => {
clearInterval(int);
};
}, []);
const defaultValue = {
a: aRef.current,
b: bRef.current,
};
return <TestContext.Provider value={defaultValue}>{children}</TestContext.Provider>;
};
taking 3 hrs
在 Context 裡存有a, b兩個值,在 Trial page 有兩個 components,分別測試不同資料型態下,a 或 b 改變,會不會影響另一個 component re-render
測試內容
useState<number>
, b 改變,會 re-render 分別使用 a, b 資料 render 的 componentuseRef.current <number>
, b 改變,會 re-render 分別使用 a, b 資料 render 的 componentuseMemo<number>
, b 為useRef.current <number>
, b 改變,會 re-render 分別使用 a, b 資料 render 的 componentuseRef.current
nested object , b 為useRef.current <number>
,a.a3.a32
改變,會 re-render 分別使用a.a3.a31
, b 資料 render 的 componentuseRef.current <Array<number>>
, b 為useRef.current <number>
,a 的 element 透過 useRef 改變,不會引起任何 re-renderuseRef.current <Array<number>>
, b 為useRef.current <number>
,a 的 element 透過 setState 改變,會 re-render 分別使用a[0]
, b 資料 render 的 component[x] a 為
useRef.current <Array<number>>
, b 為useRef.current <number>
,a 的 element 透過 setState 改變,會 re-render 分別使用a[0]
, b 資料 render 的 component,雖然 component 2 用解構賦值的方式取得 b,會有一樣的結果component 架構