我有一个组件,如下所示,它本身就可以很好地工作。我的想法是,我正在构建一个比较运算符列表,其中第一个下拉列表中选择的项目是键值对集合中的键,其中该值是一个字符串数组,该数组填充与第三个框中该键相关的选项。第二个框充当比较器选择器。
这非常适合作为组件或嵌套组件。但一旦我在
map
中渲染该组件,它就会破坏钩子系统。
将状态移出组件会很困难,因为每次迭代都需要自己的存储(也就是说,将其移动到父级,我们需要开始在索引上存储值,但只有父级知道索引,现在我们来回传递数据会让事情变得更糟)。
这里正确的范例是什么?
const Condition = () => {
const [selectables, setSelectables] = useState([]);
//This will be passed in as a prop
const vals = {
"Fruit" : ["Apple", "Orange"],
"Vegetable" : ["Cucumber", "Celery", "Onion"],
};
const filterSelectablesOnClick = (selected) => {
var newState = selected.map((item) => {
return { label: item, value: item };
});
setSelectables(newState);
};
const valKeys = Object.entries(vals).map(([key, value]) => {
return { label: key, value: key };
})
return (
<Row>
<div className="col-md-4">
<ReactSelect
options={valKeys}
onChange={(selected) => {
filterSelectablesOnClick(value);
}}
/>
</div>
<div className="col-md-4">
<Form.Select aria-label="Default select example" className="form-select flex-grow-1">
<option>Choose one...</option>
<option value="is">is</option>
<option value="is-not">is-not</option>
</Form.Select>
</div>
<div className="col-md-4">
<ReactSelect
options={selectables}
isMulti
placeholder="Select comestible..."
/>
</div>
</Row>
);
}
这适用于以下三种情况中的两种:
//In a single instance, fine
<Condition />
//In any number of multiple instances, lovely
<Condition />
<Condition />
//But not as a dynamically created and iterated component:
const [conditions, setConditions] = useState([]);
const increaseConditionCount = () => {
setConditions([...conditions, Condition()]);
};
{conditions.map((component, index) => (
<React.Fragment key={index}>
{ component }
</React.Fragment>
))}
为什么要将组件存储在状态中?您可以将数据存储在状态中并作为所需的道具传递。 所以你可以做这样的事情
const [conditionCount, setConditionCount] = useState(0);
const increaseConditionCount = () => {
setConditionCount(prevCount => prevCount + 1);
};
return (
<>
{[...Array(conditionCount)].map((_, index) => (
<Condition key={index} />
))}
</>
);