【问题标题】:Limit number of checkboxes selected and save value限制选中的复选框数量并保存值
【发布时间】:2020-07-21 18:07:42
【问题描述】:

我正在构建一个送餐应用程序,我想知道如何限制选中复选框的数量。一个例子是在进入子公司时,它会显示一个产品列表。如果我选择一个披萨,有一个附加部分限制您可以选择的附加部分的数量,如果您想选择两个以上并且您的限制是两个,则不应允许您

所有这些都带有反应钩子,我附加了我的组件的一个片段

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-native react-hooks


    【解决方案1】:

    这是带有useReducer 的“带有限制的复选框”行为的简单反应实现。这样,业务逻辑(这里是限制,但可以是任何)在组件外部以纯 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)
      
      const CheckBox = ({id}) => (
        <input
          id={id}
          onClick={() => dispatch({ id })}
          checked={state.checkedIds.includes(id)}
          type="checkbox"
        />
      )
     
      return (
        <table border="1">
          {data.map(({ id, label }) => (
            <tr>
              <td>
                <CheckBox id={id} />
              </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>

    【讨论】:

    • 看起来很不错,我会努力实现的,非常感谢✨
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 2011-02-27
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多