使用useState挂钩连续基于先前状态进行更新

时间:2019-09-04 18:21:40

标签: reactjs react-hooks

如果两个复选框都被选中,我正在尝试启用按钮,我的stackblitz link无法正常工作

我添加了功能的唯一关键。请查看无效演示的链接

    import React, { useState } from 'react';
    import { render } from 'react-dom';

    function App (){
      const [checked, toggleCheckbox] = useState({ checkbox1: false, checkbox2: false, disabled: true });
      const getDisabled = (state) => {
         if (state.checkbox1 || state.checkbox2) {
           return false;
         } else if (!state.checkbox1 && !state.checkbox2) {
           return true;
         } else {
           return true;
         }
       };
       const handleCheckbox = (checkbox) => {
        toggleCheckbox({
            ...checked,
            [checkbox]: !checked[checkbox],
            disabled: getDisabled(checked)
        });
        console.log(checked);
    };
    const checkDisable = checked.disabled ? 'disabled' : ''
    return (
      <div>
        <div>
           <label>
               <input
                    type="checkbox"
                    className="filled-in"
                    onChange={() => handleCheckbox('checkbox1')}
                    checked={checked.checkbox1}
                />
                <span className="black-text">Checkbox1</span>
            </label>
        </div>
        <div>
            <label>
                <input
                    type="checkbox"
                    className="filled-in"
                    onChange={() => handleCheckbox('checkbox2')}
                    checked={checked.checkbox2}
                />
                <span className="black-text">checkbox2</span>
            </label>
        </div>
        <div>
            <a className={checkDisable} href="#!">
                Next Step
            </a>
        </div>
   </div>
  );
}
render(<App />, document.getElementById('root'));

功能应如下:

  1. 仅当两个复选框都选中时,才应启用按钮
  2. 取消选中任何人的复选框时,应禁用该按钮

1 个答案:

答案 0 :(得分:3)

您可以简单地检查两个复选框值的状态。

  const isDisabled = !(checked.checkbox1 && checked.checkbox2)
  const checkDisable = isDisabled ? 'disabled' : ''

无需在其他地方进行更改。

分叉的堆栈闪电链接。 https://stackblitz.com/edit/react-jscqwr?file=index.js

demo


回答comment

  

嘿,那行得通!我可以在日志中看到,在单击第二个复选框{复选框{false 1:false,复选框:false,禁用:false}之后,单击实例{logbox1:true,复选框, :false,已禁用:false}

看到状态过时​​的原因是因为状态更新器toggleCheckbox批处理了更新,因此您需要检查效果中的更新状态,以监视更新状态。

how to console


复选框的动态数量。

我已经更新了堆栈以跟踪复选框的动态数量。

新叉〜 https://stackblitz.com/edit/react-pl1e2n

看起来像这样。 enter image description here

function App() {
  const length = 6;
  1️⃣ Generate the initial checkbox states - this prevents un/controlled component error.
  const initialCheckboxes = Array
    .from({ length }, (_, i) => i + 1)
    .reduce((acc, id) => (acc[id] = false, acc), {})

  const [checked, toggleCheckbox] = useState(initialCheckboxes);
  const [isDisabled, setIsDisabled] = useState(false)

  const handleCheckbox = id => {
    toggleCheckbox(previous => ({
      ...previous,
      [id]: !previous[id]
    }));
  };

  2️⃣ Update the disable state when the checkbox is selected.
  useEffect(() => {
     ? Enable when all checkboxes are not checked - ?
    setIsDisabled(!Object.values(checked).every(_ => !!_))
  }, [checked])

  3️⃣ Dynamically generate checkboxes
  const checkboxElements = Array.from({ length }, (_, i) => i + 1)
    .map(id => (
      <div key={id}>
        <label>
          <input
            type="checkbox"
            className="filled-in"
            onChange={() => handleCheckbox(id)}
            checked={checked[id]}
          />
          <span className="black-text">Checkbox{id}</span>
        </label>
      </div>
    ))


  return (
    <div>
      {checkboxElements}
      <div>
        <a className={isDisabled ? 'disabled' : ''} href="#!">
          Next Step
                            </a>
      </div>
    </div>
  );
}