搜尋

首頁  >  問答  >  主體

使用React hooks在複選框組中取消選取多個複選框

<p>我在幾個複選框組中運行了幾個複選框。我無法弄清楚如何取消選取(從而改變狀態)特定的複選框。由於某種原因,我無法訪問<code>e.target.checked</code>。 </p> <pre class="brush:php;toolbar:false;"><Checkbox size="small" name={item} value={item} checked={checkboxvalues.includes(item)} onChange={(e) => handleOnChange(e)} /></pre> <p>和我的函數</p> <pre class="brush:php;toolbar:false;">const handleOnChange = (e) => { const check = e.target.checked; setChecked(!check); };</pre> <p>我在<strong>這個sandbox</strong>中製作了一個可工作的組件範例。 </p>
P粉008829791P粉008829791459 天前471

全部回覆(2)我來回復

  • P粉322319601

    P粉3223196012023-08-31 09:00:43

    這是我如何做的:https://codesandbox.io/s/elastic-pateu-flwqvp?file=/components/Selectors.js

    我將選擇邏輯抽象化成一個useSelection()自訂鉤子,這表示目前選擇可以在store[key].selected中找到,其中 key可以是selectors的任何鍵。

    每個useSelection()調用中的itemsselectedsetSelectedsectionLabel都存儲在store[key]中,並傳遞給一個<CustomCheckboxGroup />元件。

    相關部分是該元件內的handleCheck函數,它會根據先前選擇的值設定新的選擇:如果目前item包含在先前的selected值中,則將其移除。否則,將其添加。


    更詳細的解釋(為什麼)

    仔細觀察你的程式碼,似乎你對React中的複選框元件的工作原理感到困惑。

    inputchecked屬性由一個boolean狀態控制。通用範例:

    const Checkbox = ({ label }) => {
      const [checked, setChecked] = useState(false)
      return (
        <label>
          <input
            type="checkbox"
            checked={checked}
            onChange={() => setChecked(!checked)}
          />
          <span>{label}</span>
        </label>
      )
    }
    

    每次渲染時,<input />checked值會根據checked狀態的目前值設定。當輸入的checked發生變化(使用者互動時),狀態不會自動更新。但是onChange事件被觸發,我們使用它來將狀態更新為狀態先前值的負值。


    當處理<CheckboxList />元件時,我們不能使用單一布林值來控制所有複選框 ,我們需要為正在渲染的每個複選框設定一個布林值。因此,我們建立一個selected數組,並將每個<input />checked值設為selected.includes(item) 的值(傳回一個boolean)。

    為了使其工作,我們需要在每個onChange事件中更新selected陣列的值。我們檢查item是否包含在先前版本的selected中。如果存在,則將其過濾掉。如果不存在,則將其加進去:

    const CheckboxList = ({ items }) => {
      const [selected, setSelected] = useState([])
      const onChecked = (item) =>
        setSelected((prev) =>
          prev.includes(item)
            ? prev.filter((val) => val !== item)
            : [...prev, item]
        )
    
      return items.map((item) => (
        <label key={item}>
          <input
            type="checkbox"
            checked={selected.includes(item)}
            onChange={() => onChecked(item)}
          />
          <span>{item}</span>
        </label>
      ))
    }
    

    希望這能解決一些問題。

    回覆
    0
  • P粉060528326

    P粉0605283262023-08-31 00:36:19

    您需要為每個群組建立特定的handleOnChange函數。我已經為Genre複選框組創建了一個類似的函數,您可以按照相同的方式為其他組創建。

    這是處理函數。

    const handleOnChangeGenre = (e) => {
        let newValArr = [];
        if (e.target.checked) {
          newValArr = [...state.pillarGenre.split(","), e.target.value];
        } else {
          newValArr = state.pillarGenre
            .split(",")
            .filter((theGenre) => theGenre.trim() !== e.target.value);
        }
        setState({ ...state, pillarGenre: newValArr.join(",") });
      };

    將此函數作為handleOnChange屬性傳遞給CustomCheckboxGroup,如下所示。

    <CustomCheckboxGroup
              checkboxdata={genres}
              checkboxvalues={state.pillarGenre}
              value={state.pillarGenre}
              sectionlabel="Genre"
              onToggleChange={handleGenreSwitch}
              togglechecked={genreswitch}
              handleOnChange={handleOnChangeGenre}
            />

    為了測試,請註解掉您的handleOnChange函數。

    在沙箱中查看完整的工作解決方案 - 完整程式碼

    回覆
    0
  • 取消回覆