闽公网安备 35020302035485号
const ComA = (props) => {
const { num = 1, config } = props;
return <>{num}</>;
};
// 堆代码 duidaima.com
// or
const ComA = ( { num = 1, config }) => {
return <>{num}</>;
};
// use
const App = () => {
return <ComA />;
}
大多数 Props 解构可能就是这样,确实很方便也很优雅,对于具有默认值的 Props 这是一种常见的做法。
const ComA = (props) => {
const { num = 1, config = { a: 1 } } = props;
return <>{num}</>;
};
还是很优雅,然后继续迭代,某个需求的 useEffect 突然要依赖 config.a,由于 config 只有一个属性,所以代码补全的时候直接帮你补上了 config,如下const ComA = (props) => {
const { num = 1, config = { a: 1 } } = props;
useEffect(() => {
console.log("config.a", config.a);
}, [config]);
return <>{num}</>;
};
但是随后问题袭来。
// 堆代码 duidaima.com
// App 开始控制 ComA num props 的值
export default function App() {
const [num, setNum] = useState(0);
return (
<div className="App">
<button onClick={() => setNum((prev) => prev + 1)}>setNum</button>
<br />
<ComA num={num} />
</div>
);
}

config = { type: { key: '', value: '' } }
但是究其原因都是对象重新创建的问题。
// config = { a: 1 } -> config = DEFAULT_CONFIG
const DEFAULT_CONFIG = { a: 1 };
const ComA = (props) => {
const { num = 1, config = DEFAULT_CONFIG } = props;
useEffect(() => {
console.log("config.a", config.a);
}, [ob]);
return <>{num}</>;
};

import { useState, useEffect } from "react";
const DEFAULT_CONFIG = { a: 1 };
const ComA = (props) => {
const { num = 1, config = DEFAULT_CONFIG } = props;
useEffect(() => {
console.log("config.a", config.a);
}, [config]);
return (
<>
<button
onClick={() => {
config.a = 0;
}}
>
!!set config.a!!
</button>
<br />
{num}
</>
);
};
export default function App() {
const [num, setNum] = useState(0);
const [config, setConfig] = useState();
return (
<div className="App">
<button onClick={() => setNum((prev) => prev + 1)}>setNum</button>
<button onClick={() => setConfig({ a: 2 })}>initConfig</button>
<button onClick={() => setConfig(undefined)}>resetConfig</button>
<br />
<ComA num={num} config={config} />
</div>
);
}
在上面的代码中:const DEFAULT_CONFIG = { a: 1 };
const ComA = (props) => {
const { num = 1 } = props;
const config = useMemo(() => {
return props.config ? props.config : { ...DEFAULT_CONFIG };
}, [props.config]);
useEffect(() => {
console.log("config.a", config.a);
}, [config]);
...
}
组件内部修改 Props 的值是不被建议,不符合规范的做法,但是谁能决定写 React 的人写代码的姿势呢?
import { useState, useEffect, useRef } from "react";
// 堆代码 duidaima.com
// before
// useEffect(() => {
// console.log("num", num, "config.a", config.a);
// }, [num, config]);
const ComA = (props) => {
const { num = 1, config = { a: 1 } } = props;
const configRef = useRef();
configRef.current = config.a;
useEffect(() => {
const config = configRef.current;
console.log("num", num, "config.a", config.a);
}, [num]);
return <>{num}</>;
};
export default function App() {
const [num, setNum] = useState(0);
return (
<div className="App">
<button onClick={() => setNum((prev) => prev + 1)}>setNum</button>
<br />
<ComA num={num} />
</div>
);
}
这个案例里的 useEffect 监听了 num 而不是 config,在 num 变化时再通过 useRef 拿到最新的 config,而不去关心 config 的值是不是最新的,避免 config 因为解构重复更新。
这个解决方案没有解决 config 值重复变化的问题,问题依然存在!