我创建了一个组件,当对象内的键是另一个对象时,它会添加一个额外的选择框下拉列表。
例如,考虑以下对象:
{
a1: {
x1: 1,
x2: 2,
x3: 3,
x4: {
z1: "z1",
z2: "z2"
},
x5: [
{
x5a: {
z5a1: 1,
z5a2: 2
}
},
{
x5b: {
z5b1: 1,
z5b2: 2
}
}
]
},
a2: {
x1: 1,
x2: 2,
x3: 3
},
a3: "some values"
};
我想要实现的是(当我从下拉菜单中选择 value
时):
subTree[value]
是一个对象 ({}
) 或一个数组 ([]
),在
一个新的选择框下拉,直接在当前的下方选择一个值后,下一个选择将显示为空,依此类推...
当我更新选择框中的值时,我的代码不会正确更新/清除下面的选择。
我的项目的源代码位于:https://codesandbox.io/s/frosty-grass-9jdue
答案 0 :(得分:1)
当更改不是路径中最后一个值时,您需要清除所有后续选择,因为它们基于不同的路径。我不太确定我们在你的设置中如何做到这一点,因为我还没有完全理解它。
对我来说有意义的是将路径的各个部分存储为 # module_b/pack_b.py
from module_a import AClass1 # <-, I get an issue here
。这样我们就可以使用 array
去除尾部。我将使用 lodash's get
method 作为助手来访问路径上的值。我希望道具 slice
是对象本身,而不是像您之前所做的那样 data
。
Object.entries
答案 1 :(得分:1)
来自@LindaPaiste 的回答:
<块引用>当更改不是路径中最后一个值时,您需要清除所有后续选择,因为它们基于不同的路径。
这是解决问题的关键!您必须以某种方式吹走并忘记您当前正在更改其 value
的选择框下方的所有内容。
React 是围绕 "blow away and forget" principle 设计的。还要注意 The Data Flows Down。考虑到这一点,您的任务应该很容易完成,虽然 Linda 的解决方案似乎有效,但它可能并不那么简单。
如果我们可以有一个特殊的组件,(1) 接受数据的子树,(2) 将其第一级子项呈现为选择框下拉列表,然后 (3) 递归地重复该过程,该怎么办?像这样:
<RecursiveComponent subTree={DATA_SAMPLE} {/*maybe some other props*/}/>
当我们想到递归时,我们必须想到终止条件。在我们的例子中,当子树是原始类型(即不是对象 ({}
) 或数组 ([]
))时,会发生这种情况。
每个 RecursiveComponent
都必须:
RecursiveComponent
,基于 props.subTree[selection]
像这样:
import { MenuItem, Select } from "@material-ui/core";
import { useState } from "react";
function RecursiveComponent(props) {
const [selection, setSelection] = useState(props.currentSelection);
const handleChange = (event) => {
setSelection(event.target.value);
};
return (
<>
<Select variant="outlined" value={selection} onChange={handleChange}>
{Object.keys(props.subTree).map((key) => (
<MenuItem value={key}>{key}</MenuItem>
))}
</Select>
<div /> {/* forces a line break between selection boxes */}
{props.subTree[selection] !== Object(props.subTree[selection]) ? (
<></>
) : (
<RecursiveComponent
subTree={props.subTree[selection]}
currentSelection=""
/>
)}
</>
);
}
export default RecursiveComponent;
这是通过编辑 RecursiveComponent
在项目中使用 index.js
的方法:
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { DATA_SAMPLE } from "./DataSample";
import RecursiveComponent from "./RecursiveComponent";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<RecursiveComponent subTree={DATA_SAMPLE} currentSelection="" />
</StrictMode>,
rootElement
);