我正在构建一个送餐应用程序,我想知道如何限制所选复选框的数量。例如,当输入子公司时,它会显示一个产品列表。如果我选择一个披萨,有一个额外部分限制了你可以选择的额外数量,如果你想选择两个以上,并且你的限制是两个,它不应该允许你
所有这些都与反作用挂钩,我附加了我的组件的一个片段
const ExtrasSelector = ({options = [{}], onPress = () => {}, limit = 0}) => {
const [showOptions, setShowOptions] = useState(true);
const [selectedAmount, setSelectedAmount] = useState(0);
const EXTRA = ' extra';
const EXTRAS = ' extras';
const updatedList = options.map(data => ({
id: data.id,
name: data.name,
price: data.price,
selected: false,
}));
const [itemsList, setItemsList] = useState(updatedList);
const toggleOptions = () => setShowOptions(!showOptions);
useEffect(() => {
}, [selectedAmount]);
// onPress for each check-box
const onPressHandler = index => {
setItemsList(state => {
state[index].selected = !state[index].selected;
onPress(state[index], getSelectedExtras(state));
// Increments or decreases the amount of selected extras
if (state[index].selected) {
setSelectedAmount(prevState => prevState + 1);
} else {
setSelectedAmount(prevState => prevState - 1);
}
return state;
});
};
const getSelectedExtras = extrasArr => {
const selectedExsArr = [];
extrasArr.map(item => {
if (item.selected) {
selectedExsArr.push(item);
}
});
return selectedExsArr;
};
return (
<View>
<View style={styles.container}>
<TouchableOpacity style={styles.row} onPress={toggleOptions}>
<Text style={styles.boldTitleSection}>
Extras {'n'}
<Text style={titleSection}>
Selecciona hasta {limit}
{limit > 1 ? EXTRAS : EXTRA}
</Text>
</Text>
<View style={styles.contentAngle}>
<View style={styles.contentWrapperAngle}>
<Icon
style={styles.angle}
name={showOptions ? 'angle-up' : 'angle-down'}
/>
</View>
</View>
</TouchableOpacity>
{showOptions ? (
itemsList.map((item, index) => (
<View key={index}>
<CheckBox
label={item.name}
price={item.price}
selected={item.selected}
otherAction={item.otherAction}
onPress={() => {
onPressHandler(index, item);
}}
/>
<View style={styles.breakRule} />
</View>
))
) : (
<View style={styles.breakRule} />
)}
</View>
</View>
);
};
这是一个简单的react实现"带有限制的复选框";CCD_ 1的行为。通过这种方式,业务逻辑(这里是限制,但可以是任何限制(在组件之外的纯js函数中实现,而组件本身只是一个简单的可重用复选框组。
const { useReducer } = React; // --> for inline use
// import React, { useReducer } from 'react'; // --> for real project
const reducer = (state, action) => {
if (state.checkedIds.includes(action.id)) {
return {
...state,
checkedIds: state.checkedIds.filter(id => id !== action.id)
}
}
if (state.checkedIds.length >= 3) {
console.log('Max 3 extras allowed.')
return state;
}
return {
...state,
checkedIds: [
...state.checkedIds,
action.id
]
}
}
const CheckBoxGroup = ({ data }) => {
const initialState = { checkedIds: [] }
const [state, dispatch] = useReducer(reducer, initialState)
return (
<table border="1">
{data.map(({ id, label }) => (
<tr key={id}>
<td>
<input
onClick={() => dispatch({ id })}
checked={state.checkedIds.includes(id)}
type="checkbox"
/>
</td>
<td>
{label}
</td>
</tr>
))}
</table>
)
};
const data = [
{ id: "1", label: "Mashroom" },
{ id: "2", label: "Ham" },
{ id: "3", label: "Egg" },
{ id: "4", label: "Ananas" },
{ id: "5", label: "Parmesan" },
]
ReactDOM.render(<CheckBoxGroup data={data} />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>