情况1 (同2、4结论一致)
- 定义:使用子hook,将数据 const a = 【对stateX的一系列操作】 封存到子hook里。并return出去。
- 结果:此种情况不影响实时渲染。
- 缺点:只要stateX变更,一定展示c的最新数据。但是若有其他state变更,也会导致c的赋值行为再走一遍。这样会导致不必要的计算
const useTest = () => {
const [testa, setTesta] = useState(false);
const a = testa ? Math.random() : 0;
return { a, setTesta, testa };
};
function Component(){
const { a, setTesta, testa } = useTest();
return <div>//使用a进行渲染相关操作</div>
}
情况2
- 定义: const c = useRef() 或 全局const c = { xx: xx };
- 修改: 通过 c.xx = 【对stateX的一系列操作】 修改c的内容。
- 结果:此种情况不影响实时渲染。
- 缺点:但是若有其他state变更,也会导致c的赋值行为再走一遍。这样会导致不必要的计算
function Component(){
const [test, setTest] = useState(false);
const c = useRef(0)
c.current = test ? Math.random() : 0;
return <div>//使用c.current进行渲染相关操作</div>
}
或
const c = { current: 0 }//组件外的全局变量
function Component(){
const [test, setTest] = useState(false);
c.current = test ? Math.random() : 0;
return <div>//使用c.current进行渲染相关操作</div>
}
情况3
- 定义: const c = useRef() 或 全局const c = { xx: xx };
- 修改: useEffect监听stateX && 通过 c.current = 【对stateX的一系列操作】 修改c的内容。
- 结果: 此种情况影响实时渲染,页面上展示的c.current 是前一次的数据。
- 原因:useEffect 在渲染后执行,c.current 的更新不会触发新一轮渲染,新值需等到下次渲染才会显示。
function Component(){
const [test, setTest] = useState(false);
const c = useRef(0)
useEffect(() => {
c.current = test ? Math.random() : 0;
}, [test]);
return <div>...使用c.current进行渲染相关操作</div>
}
或
const c = { current: 0 }//组件外的全局变量
function Component(){
const [test, setTest] = useState(false);
useEffect(() => {
c.current = test ? Math.random() : 0;
}, [test]);
return <div>...使用c.current进行渲染相关操作</div>
}
情况4
- 定义: 组件内,const c = { xx: xx };
- 修改: 通过 c.xxx = 【对stateX的一系列操作】 修改c的内容。
- 结果:此种情况不影响实时渲染。
- 缺点:只要stateX变更,一定展示c的最新数据。但是若有其他state变更,也会导致c的赋值行为再走一遍。这样会导致不必要的计算
function Component(){
const [test, setTest] = useState(false);
const c = {current:0}
c.current = test ? Math.random() : 0;
return <div>...使用c.current进行渲染相关操作</div>
}
情况5
- 定义: 组件内,const c = { xx: xx };
- 修改: useEffect监听stateX && 通过 c.current = 【对stateX的一系列操作】 修改c的内容。
- 结果: 此种情况影响实时渲染,页面上展示的c.current ⚠️一直不变。
- 原因:useEffect 在渲染后执行,b.current 的更新不会触发新一轮渲染,下一轮更新时,新值又被定义时的值覆盖了。
function Component(){
const [test, setTest] = useState(false);
const c = {current:0}
useEffect(() => {
c.current = test ? Math.random() : 0;
}, [test]);
return <div>...使用c.current进行渲染相关操作</div>
}
总结:
-
若,某些内容跟 【状态变量】(特指:使用useState管理的数据)有一些简单的关联性,且需要渲染。比如简单的取反、取长度之类的。则可以考虑 使用
c = 【对stateX的一系列操作】
或渲染时直接arr.length
这种类似操作,来进行赋值和展示。不需要特地使用 state管理起来。这样比较浪费资源。
若,某些内容跟 【状态变量】(特指:使用useState管理的数据)有一些复杂的关联性,比较耗费性能那种,则需要特地使用 state管理起来,并使用useEffect监听相关状态,并进行复杂的赋值。 -
useEffect内更新的数据,要么是使用 state管理起来。要么是跟渲染一点关系没有的。
-
useRef 相当于 定义了一个全局变量。所以,他不会每次组件发生更新,都走重新赋值的操作。