如何将字符串插入数组的次数与输入的 int 值相同?
How to insert a string into an array the same amount of times as the int value from an input?
我有这个猫鼬模式
const storeSchema = mongoose.Schema({
name: {
type: String,
required: true,
},
fruits: {
type: [String],
required: true,
},
});
在我的客户端,我正在为名称输入执行此操作,到目前为止它正在运行。
const [store, setStoreData] = useState({
store: '',
fruits: [''],
});
const dispatch = useDispatch();
const handleSubmit = (e) => {
e.preventDefault();
dispatch(addStore(store));
};
...
<TextField
label='Store Name'
variant='outlined'
value={store.name}
onChange={(e) =>
setStoreData({
...store,
name: e.target.value,
})
}
/>
我试图模仿这种行为,但我认为它必须更复杂。问题是我想为每个水果设置 2 或 3 个这样的“输入 select”。每个都有多个 int 选择,如 1、2、3。并根据目标值,将水果数量推入 fruits 数组。这就是我的。
<Select
value={store.fruits}
label='Fruits'
onChange={(e) =>
setStoreData({
...store,
fruits: e.target.value,
})
}>
<MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem>
<MenuItem value={3}>3</MenuItem>
</Select>
所以理想情况下,我会有 3 个这样的输入,一个用于每种水果,如香蕉和苹果,并且客户选择的数字将是香蕉将插入到数组中的条目数。
示例:select 表示我有 3 个(数字 3)香蕉。
我会在数据库中得到这个。
{
"name": store
"fruits": ["banana", "banana", "banana"]
}
我正在使用@mui/material 进行反应。
一个好的解决方案可能是将您的状态结构更改为输入更友好的结构,然后在提交时将此值转换为与您的商店架构匹配的结构。
您的州声明可能看起来像这样;
const [store, setStoreData] = useState({
name: "",
fruits: {
apple: 0,
banana: 0,
orange: 0
},
});
然后您可以使用共享方法来更新您所在州的水果值。
const handleChangeFruit = (name, value) => {
setStoreData(store => ({
...store,
fruits: {
...store.fruits,
[name]: value
}
}));
}
然后你的水果Select
输入变成:
<Select
value={store.fruits.apple}
label='apple'
onChange={(e) =>
handleChangeFruit('apple', parseInt(e.target.value))
}>
<MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem>
<MenuItem value={3}>3</MenuItem>
</Select>
要将此状态转换为您的模式形状,您可以执行如下操作;
const getStoreData = () => {
const fruits = Object.entries(store.fruits).reduce(
(acc, cur) => acc.concat(new Array(cur[1]).fill(cur[0])),
[]
);
return {
name: store.name,
fruits,
};
};
您的 handleSubmit
方法现在变为:
const handleSubmit = (e) => {
e.preventDefault();
dispatch(addStore(getStoreData()));
};
这应该可以解决问题。
为了获得额外的智能点,您甚至可以像这样动态生成 Select
字段:
Object.keys(store.fruits).map((fruit) => (
<Select
key={fruit}
value={store.fruits[fruit]}
label={fruit}
onChange={(e) => handleChangeFruit(fruit, parseInt(e.target.value))}
>
<MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem>
<MenuItem value={3}>3</MenuItem>
</Select>
));
我有这个猫鼬模式
const storeSchema = mongoose.Schema({
name: {
type: String,
required: true,
},
fruits: {
type: [String],
required: true,
},
});
在我的客户端,我正在为名称输入执行此操作,到目前为止它正在运行。
const [store, setStoreData] = useState({
store: '',
fruits: [''],
});
const dispatch = useDispatch();
const handleSubmit = (e) => {
e.preventDefault();
dispatch(addStore(store));
};
...
<TextField
label='Store Name'
variant='outlined'
value={store.name}
onChange={(e) =>
setStoreData({
...store,
name: e.target.value,
})
}
/>
我试图模仿这种行为,但我认为它必须更复杂。问题是我想为每个水果设置 2 或 3 个这样的“输入 select”。每个都有多个 int 选择,如 1、2、3。并根据目标值,将水果数量推入 fruits 数组。这就是我的。
<Select
value={store.fruits}
label='Fruits'
onChange={(e) =>
setStoreData({
...store,
fruits: e.target.value,
})
}>
<MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem>
<MenuItem value={3}>3</MenuItem>
</Select>
所以理想情况下,我会有 3 个这样的输入,一个用于每种水果,如香蕉和苹果,并且客户选择的数字将是香蕉将插入到数组中的条目数。
示例:select 表示我有 3 个(数字 3)香蕉。 我会在数据库中得到这个。
{
"name": store
"fruits": ["banana", "banana", "banana"]
}
我正在使用@mui/material 进行反应。
一个好的解决方案可能是将您的状态结构更改为输入更友好的结构,然后在提交时将此值转换为与您的商店架构匹配的结构。
您的州声明可能看起来像这样;
const [store, setStoreData] = useState({
name: "",
fruits: {
apple: 0,
banana: 0,
orange: 0
},
});
然后您可以使用共享方法来更新您所在州的水果值。
const handleChangeFruit = (name, value) => {
setStoreData(store => ({
...store,
fruits: {
...store.fruits,
[name]: value
}
}));
}
然后你的水果Select
输入变成:
<Select
value={store.fruits.apple}
label='apple'
onChange={(e) =>
handleChangeFruit('apple', parseInt(e.target.value))
}>
<MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem>
<MenuItem value={3}>3</MenuItem>
</Select>
要将此状态转换为您的模式形状,您可以执行如下操作;
const getStoreData = () => {
const fruits = Object.entries(store.fruits).reduce(
(acc, cur) => acc.concat(new Array(cur[1]).fill(cur[0])),
[]
);
return {
name: store.name,
fruits,
};
};
您的 handleSubmit
方法现在变为:
const handleSubmit = (e) => {
e.preventDefault();
dispatch(addStore(getStoreData()));
};
这应该可以解决问题。
为了获得额外的智能点,您甚至可以像这样动态生成 Select
字段:
Object.keys(store.fruits).map((fruit) => (
<Select
key={fruit}
value={store.fruits[fruit]}
label={fruit}
onChange={(e) => handleChangeFruit(fruit, parseInt(e.target.value))}
>
<MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem>
<MenuItem value={3}>3</MenuItem>
</Select>
));