反应验证动态复选框

时间:2020-08-16 09:32:31

标签: reactjs

我有7个在地图方法中呈现的复选框。每个复选框都有一个问题,当所有复选框都选中时,应该激活一个按钮..有人可以告诉我如何使用useState()钩子对此进行验证吗? ..我知道如何使用一个复选框来执行此操作,但是我不知道如何处理在map方法中呈现的多个复选框。一个代码示例应该会很有帮助。任何帮助将不胜感激。

const [isChecked, setIsChecked] = useState(false);

{ questions.map(q => (
                  <input
                    type={q.radio ? "radio" : "checkbox"}
                    onClick={() => setIsChecked(!isChecked)}
                    value={isChecked}
                    id={option.id}
                    value={option.value}
                    name={`${q.name}`}
                  />

使用此map方法呈现的复选框有7个。在这种情况下,我应该如何处理状态?

6 个答案:

答案 0 :(得分:0)

如果您的问题是动态列表,则可以使用以下方法:

const QUESTIONS = ["Do you use Stackoverflow?", "Do you asked a question?"];

function Confirmation({ data }) {
  const [questions, setQuestions] = React.useState(
    data.map((question, index) => {
      return { id: index, text: question, checked: false };
    })
  );

  const handleClick = (id, checked) => {
    const newQuestions = [...questions];
    const index = newQuestions.findIndex((q) => q.id === id);
    newQuestions[index].checked = checked;

    setQuestions(newQuestions);
  };

  const isButtonDisabled = questions.some((q) => q.checked === false);

  return (
    <div>
      {questions.map((question) => (
        <React.Fragment>
          <input
            key={question.id}
            name={`question-${question.id}`}
            type="checkbox"
            checked={question.checked}
            onClick={(e) => handleClick(question.id, e.target.checked)}
          />
          <label htmlFor={`question-${question.id}`}>{question.text}</label>
        </React.Fragment>
      ))}
      <button disabled={isButtonDisabled}>Confirm</button>
    </div>
  );
}

ReactDOM.render(<Confirmation data={QUESTIONS} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

答案 1 :(得分:0)

要添加到dude的答案中,您可以根据对问题数组的更改来动态调整checked数组,这样您就不必手动维护初始状态或记住将其同步到新的长度。问它是否改变。

const [checked, setChecked] = useState([])

const arrLength = questions.length;
useEffect(() => {
  setChecked(() => (
    Array(arrLength).fill().map((_, i) => checked[i] || false)
  ));
}, [arrLength]);

答案 2 :(得分:0)

以下是您的问题映射示例。 您可以将这些问题加载到useState中,并将检查值附加到这些问题上。

点击下面的运行代码段以查看其正常运行。

const { useState, useEffect } = React;

const App = props => {
  const { questions } = props;
  const [state, setState] = useState(null);
  
  const onChangeCheckbox = index => event => {
    const newState = [...state];
    newState[index].checked = !newState[index].checked;
    setState(newState);
  }
  
  useEffect(() => {
    setState(questions.map(i => ({...i, checked: false }) ));
  }, [questions]);
  
  // Not loaded yet
  if (!state) return <div></div>; 
  
  return <div>
    {state && state.length > 0 && <div>
       {state.map((i, k) => <p key={`question-${k}`}>
        <label><input onChange={onChangeCheckbox(k)} type="checkbox" name={i.name} checked={i.checked} />&nbsp;{i.question}</label>
       </p>)}
    </div>}
    <hr />
    <p><small>Debug</small></p>
    <pre><code>{JSON.stringify(state, null, ' ')}</code></pre>
  </div>;
};

const questions = [
{
  name: 'cyborg',
  question: 'Are you a cyborg?'
},
{
  name: 'earth',
  question: 'Do you live on earth?'
},
{
  name: 'alien',
  question: 'Are you from another planet?'
}
];


ReactDOM.render(<App questions={questions} />, document.querySelector('#root'));
body {
  font-family: Arial, sans-serif;
}

pre {
  background: #efefef;
  padding: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="root"></div>

答案 3 :(得分:0)

使用关键参数为每个复选框指定一个标识符,以便可以对其进行修改。

const [isChecked, setIsChecked] = useState([])
useEffect(() => {
     compareList()
        
    })
    { questions.map((q,i) => (
                      <input
                        type={q.radio ? "radio" : "checkbox"}
                        onClick={() => setIsChecked(!isChecked[i])}
                        value={isChecked[i]}
                        id={option.id}
                        value={option.value}
                        name={`${q.name}`}
                        key=i
                      />

答案 4 :(得分:0)

如果您使用受控输入,则解决方案可能是这样的:

const initialState = [
  {
    name: "Check option 1",
    checked: false
  },
  {
    name: "Check option 2",
    checked: false
  },
]

const App = () => {
  const [checkboxes, setCheckboxes] = useState(initialState)
  const [quizFinished, setQuizFinished] = useState(false)
  // the useEffect checks if all questions are completed
  useEffect(()=>{
    setQuizFinished(checkboxes.reduce((acc, cbx) => acc && cbx.checked, true))
  }, [checkboxes])
  
  function handleChange(e) {
    setCheckboxes(
      checkboxes.map(cbx => cbx.name === e.target.name ? {...cbx, checked:!cbx.checked} : cbx)
    )
  }
  return (
    <>
      {checkboxes.map(cbx => <Checkbox name={cbx.name} checked={cbx.checked} onChange={handleChange}/>)}
      {quizFinished && <button>Finish</button>}
    </>
  )
}

const Checkbox = ({name, checked, onChange}) => {
  return (
    <>
      <label>
        {name}
        <input type="checkbox" name={name} checked={checked} onChange={onChange} />
      </label>
      <br/>
    </>
  )
}

答案 5 :(得分:-1)

您可以对状态进行建模以适合您的用例。对于7个复选框的列表,您可以具有7个值的数组:

const [checked, setChecked] = useState([false, false, false, false, false, false, false])

单击复选框的时间:

{ questions.map((q, i) => (
              <input
                type={q.radio ? "radio" : "checkbox"}
                onClick={() => setChecked(current => {
                   const newState = [...current]
                   newState[i] = !newState[i]
                   return newState
                } )}
                value={checked[i]}
                id={option.id}
                value={option.value}
                name={`${q.name}`}
              />

要知道是否全部选中,可以定义一个变量:

const areAllChecked = checked.every(Boolean)