我正在尝试使用 React 和 Leva js 创建一个简单的应用程序。
基本上有一个项目数组,每个项目都有一个名称和一个数字数组。 Leva 面板包含两个选择,用户可以从项目数组中选择两个项目。
如果两个选定的项目具有相同的长度,则可以,否则应用程序应返回错误。
这里是主要代码和这是一个工作演示 https://codesandbox.io/s/test-qg5xs7?file=/src/App.jsx.
App.jsx:
export const App = () => {
const [haveSameNumberOfValues, setHaveSameNumberOfValues] = useState(true);
const [showResult, setShowResult] = useState(haveSameNumberOfValues);
const { startValuesName, endValuesName } = useControls({
startValuesName: {
value: VALUES[0].name,
options: VALUES.map((d) => d.name)
},
endValuesName: { value: VALUES[1].name, options: VALUES.map((d) => d.name) }
});
useEffect(() => {
const startValuesItem = getValuesFromName(startValuesName);
const endValuesItem = getValuesFromName(endValuesName);
const startValues = startValuesItem.values;
const endValues = endValuesItem.values;
const values = [startValues, endValues];
const valuesLenght = values.map((path) => path.length);
const haveValuesTheSameNumberOfItems = valuesLenght.every(
(pathLength) => pathLength === valuesLenght[0]
);
setHaveSameNumberOfValues(haveValuesTheSameNumberOfItems);
setShowResult(haveValuesTheSameNumberOfItems);
}, [startValuesName, endValuesName]);
console.log("\n");
console.log("haveSameNumberOfValues:", haveSameNumberOfValues);
console.log("showResult:", showResult);
return (
<div className="w-screen h-screen flex flex-col justify-center items-center">
{!haveSameNumberOfValues && <div>:( Error.</div>}
{showResult && (
<Result
startValues={getValuesFromName(startValuesName)}
endValues={getValuesFromName(endValuesName)}
/>
)}
</div>
);
};
结果.jsx:
export const Result = ({ startValues, endValues }) => {
console.log("startValues:", startValues.values.length);
console.log("endValues:", endValues.values.length);
return (
<div className="border-4 border-green-400 px-5 py-3">
<div>:)</div>
<div>{startValues.name}</div>
<div>{endValues.name}</div>
</div>
);
};
data.js:
export const VALUES = [
{
name: "carrot (3)",
values: [0, 4, 45]
},
{
name: "apple (3)",
values: [20, 20, 10]
},
{
name: "salad (4)",
values: [30, 0, 2, 1]
},
{
name: "chicken (6)",
values: [40, 1, 3, 20, 3, 1]
}
];
export function getValuesFromName(name) {
return VALUES.find((d) => d.name === name);
}
问题是,当用户选择值长度不等于的两个项目(例如胡萝卜和鸡肉)时,代码集showResult
为真所以Result
即使不应该渲染组件也会被渲染。
您可以通过阅读日志消息来检查它。
我试图使用整个示例流程更好地解释自己。
- 刷新页面,选中的项目为
carrot (3)
and apple (3)
。这些值具有相同的长度,在控制台中您可以看到:
haveSameNumberOfValues: true
showResult: true
startValues: 3
endValues: 3
showResult
是真的所以Result
组件被渲染。好的,可以了
- 用户选择
chiken (6)
as endValuesName
。控制台打印:
haveSameNumberOfValues: true
showResult: true
startValues: 3
endValues: 6
haveSameNumberOfValues: false
showResult: false
showResult
第一次是正确的,所以Result
组件被渲染,然后它发生变化并变为 false。这很奇怪,因为我不想要那样,我想立即拥有showResult=false
。这是因为在我的简单示例中,这不会造成大问题,但在我的实际应用程序中它会破坏应用程序。
我的代码有什么问题吗?
我重复一下我想要的:
用户使用 Leva 更改值 ->showResult
应在第一次调用之前以正确的方式更新Result