下一个 JS - 复选框 Select 全部

Next JS - Checkbox Select All

我是 Next Js 的初学者。我正在尝试在复选框上实现 select。

我关注这个参考 https://www.freecodecamp.org/news/how-to-work-with-multiple-checkboxes-in-react/

我期望的是,如果复选框 select 全部被选中,则对所有价格求和。

但我不知道如何开始。

这是我的沙盒https://codesandbox.io/s/eager-feather-2ieme9

任何对此的帮助将不胜感激,已经为此工作了一段时间并且用尽了所有途径!

您可以通过一些解释检查以下逻辑

您也可以查看 this sandbox 进行测试

import { useState } from "react";
import { toppings } from "./utils/toppings";
// import InputTopings from "./InputTopings";
const getFormattedPrice = (price) => `$${price.toFixed(2)}`;

export default function TopingApp() {
  const [checkedState, setCheckedState] = useState(
    new Array(toppings.length).fill(false)
  );

  // console.log(checkedState);
  const [total, setTotal] = useState(0);

  //Separate `updateTotal` logic for avoiding duplication
  const updateTotal = (checkboxValues) => {
    const totalPrice = checkboxValues.reduce((sum, currentState, index) => {
      if (currentState === true) {
        return sum + toppings[index].price;
      }
      return sum;
    }, 0);

    setTotal(totalPrice);
  };

  const handleOnChange = (position) => {
    const updatedCheckedState = checkedState.map((item, index) =>
      index === position ? !item : item
    );

    setCheckedState(updatedCheckedState);
    //update total
    updateTotal(updatedCheckedState);
  };

  const handleSelectAll = (event) => {
    //filled all checkboxes' states with `Check All` value
    const updatedCheckedState = new Array(toppings.length).fill(
      event.target.checked
    );

    setCheckedState(updatedCheckedState);
    //update total
    updateTotal(updatedCheckedState);
  };

  return (
    <div className="App">
      <h3>Select Toppings</h3>
      <div className="call">
        <input
          type="checkbox"
          name="checkall"
          checked={checkedState.every((value) => value)}
          onChange={handleSelectAll}
        />
        <label htmlFor="checkall">Check All</label>
      </div>
      <ul className="toppings-list">
        {toppings.map(({ name, price }, index) => {
          return (
            <li key={index}>
              <div className="toppings-list-item">
                <div className="left-section">
                  <input
                    type="checkbox"
                    // id={`custom-checkbox-${index}`}
                    name={name}
                    value={name}
                    checked={checkedState[index]}
                    onChange={() => handleOnChange(index)}
                  />
                  <label>{name}</label>
                </div>
                <div className="right-section">{getFormattedPrice(price)}</div>
              </div>
            </li>
          );
        })}
        <li>
          <div className="toppings-list-item">
            <div className="left-section">Total:</div>
            <div className="right-section">{getFormattedPrice(total)}</div>
          </div>
        </li>
      </ul>
    </div>
  );
}

您可以将 'Check all' 状态提升到父对象,并在更改此状态时将所有 <input/> 标签值设置为该状态,您可以通过划分应用程序来实现此目的。首先为列表中的项目创建一个组件,如 <Toppings/> 并像这样 <Toppings name={name} price={price} checkAll={checkAll}/> 为该组件提供道具,在浇头组件中创建一个状态变量,如

const Toppings = ({name,price, checkAll}) => {
    const [checked,setChecked] = useState(checkAll)
    return (
       <li key={index}>
          <div className="toppings-list-item">
            <div className="left-section">
              <input
                type="checkbox"
                // id={`custom-checkbox-${index}`}
                name={name}
                value={checked}
                onChange={setChecked(!checked)}
              />
              <label>{name}</label>
            </div>
          </div>
        </li>
     )
}

编辑:

里面 index.js:

const [checkAll, setCheckAll] = useState(false)


//when rendering inside return method 
 {toppings.map(({name,price},index) => <Toppings key={index} name={name} price={price} checkAll={checkAll}/> )