【问题标题】:Update state with radio button values React使用单选按钮值更新状态
【发布时间】:2021-10-12 13:50:07
【问题描述】:

想知道更新或设置存储单选按钮答案值的状态的正确方法是什么。这是一个有 20 个问题的性格测试,我想存储 20 个答案。我在每个单选按钮输入上都有 onChange。

我的目标是将结果数据存储为如下结构:

[opn1:1,csn1:3,ext1:2,agg1:5,neu1:4,...]

但如果我只能以正确的顺序存储答案值,那就足够了。问题在于,用户可以修改他/她的答案,然后结果状态的顺序会被混淆。

我的代码: (它不起作用,只在结果状态中存储一个答案)

function Test() {
  const [questions, setQuestions] = useState([]);
  const [answers, setAnswers] = useState([]);
  const [data, setData] = useState(false);
  const [result, setResult] = useState([]);
  const [index, setIndex] = useState(0);
  useEffect(() => {
    StudentService.getTest().then((res) => {
      setQuestions(res.questions);
      setAnswers(res.answers);
      setData(true);
    });
  }, []);

  const onStoreAnswers = (e) => {
    e.preventDefault();
  };
  const storeAnswer = (e) => {
    const qst_id = e.target.id;
    const answ_value = e.target.value;
    setResult((prevState) => ({
      ...prevState,
      qst_id: qst_id,
      answ_value: answ_value,
    }));
  };
  console.log(result);
  if (data) {
    return (
      <form className="container shadow-lg">
        <h1>I am someone who...</h1>
        <h4>{questions[index + 1].qst_title}</h4>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index].qst_id}
            value={index + 1}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox1">
            {answers[index].answ_id}
          </label>
        </div>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 1].qst_id}
            value={index + 2}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox2">
            {answers[index + 1].answ_id}
          </label>
        </div>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 2].qst_id}
            value={index + 3}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox3">
            {answers[index + 2].answ_id}
          </label>
        </div>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 3].qst_id}
            value={index + 4}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox4">
            {answers[index + 3].answ_id}
          </label>
        </div>

        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index + 1].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 4].qst_id}
            value={index + 5}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox5">
            {answers[index + 4].answ_id}
          </label>
        </div>
        <h4>{questions[index + 2].qst_title}</h4>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index + 1].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index].qst_id}
            value={index + 1}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox1">
            {answers[index].answ_id}
          </label>
        </div>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index + 1].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 1].qst_id}
            value={index + 2}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox2">
            {answers[index + 1].answ_id}
          </label>
        </div>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index + 1].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 2].qst_id}
            value={index + 3}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox3">
            {answers[index + 2].answ_id}
          </label>
        </div>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index + 1].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 3].qst_id}
            value={index + 4}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox4">
            {answers[index + 3].answ_id}
          </label>
        </div>
        <div className="form-check form-check-inline">
          <input
            onChange={storeAnswer}
            name={questions[index + 1].qst_id}
            className="form-check-input"
            type="radio"
            id={questions[index + 4].qst_id}
            value={index + 5}
          />
          <label className="form-check-label" htmlFor="inlineCheckbox5">
            {answers[index + 4].answ_id}
          </label>
        </div>
        <h4>{questions[index + 3].qst_title}</h4>
        <h4>{questions[index + 4].qst_title}</h4>
        <button onClick={onStoreAnswers}>Next Page</button>
      </form>
    );
  }
  return (
    <div className="text-center">
      <Spinner className="spinner" animation="border" />
    </div>
  );
}

export default Test;
   "answers":[
      {
         "answ_id":1,
         "answ_title":"Strongly Disagree"
      },
      {
         "answ_id":2,
         "answ_title":"Disagree"
      },
      {
         "answ_id":3,
         "answ_title":"Neither agree nor disagree"
      },
      {
         "answ_id":4,
         "answ_title":"Agree"
      },
      {
         "answ_id":5,
         "answ_title":"Strongly Agree"
      }
   ],
   "questions":[
      {
         "qst_id":"opn1",
         "qst_title":"Is outgoing, sociable"
      },
      {
         "qst_id":"csn1",
         "qst_title":"Very organized and always prepared"
      },
      {
         "qst_id":"ext1",
         "qst_title":"The life of party"
      },
      {
         "qst_id":"agg1",
         "qst_title":"Have a soft heart"
      },
      {
         "qst_id":"neu1",
         "qst_title":"Got stressed out easily"
      },
      {
         "qst_id":"opn2",
         "qst_title":"Full of ideas"
      },
      {
         "qst_id":"csn2",
         "qst_title":"Always pay attention to details"
      },
      {
         "qst_id":"ext2",
         "qst_title":"Feel comfortable around people"
      },
      {
         "qst_id":"agg2",
         "qst_title":"Intrested in people"
      },
      {
         "qst_id":"neu2",
         "qst_title":"Relaxed most of the time"
      },
      {
         "qst_id":"opn3",
         "qst_title":"Do not have a good imagination"
      },
      {
         "qst_id":"csn3",
         "qst_title":"Procrastinate too much"
      },
      {
         "qst_id":"ext3",
         "qst_title":"Do not talk a lot"
      },
      {
         "qst_id":"agg3",
         "qst_title":"Not really interested in other people's problems"
      },
      {
         "qst_id":"neu3",
         "qst_title":"Seldom feel blue"
      },
      {
         "qst_id":"opn4",
         "qst_title":"Have difficulty understanding abstract ideas"
      },
      {
         "qst_id":"csn4",
         "qst_title":"Tend to make a mess of things"
      },
      {
         "qst_id":"ext4",
         "qst_title":"Quite around strangers"
      },
      {
         "qst_id":"agg4",
         "qst_title":"Feel little concern for others"
      },
      {
         "qst_id":"neu4",
         "qst_title":"Have frequent mood swings"
      }
   ]
}

当前结果状态如下所示:

如果有人知道如何简化我的代码并使我的代码更具可读性,我愿意接受。最后,我想在页面之间切换,每个页面都会有5个问题。

【问题讨论】:

    标签: javascript arrays reactjs use-state


    【解决方案1】:

    一种看待它的方式是:您可以将每个答案视为一个键值对。键是问题标识符或键,值是答案。

    const [answers, setAnswers] = useState({});
    
    const handleAnswerAdd = (questionKey, answer) => ({
       ...answers,
       [questionKey]: answer
    }); 
    
    const questions = [
          {
             "qst_id":"opn1",
             "qst_title":"Is outgoing, sociable"
          },
          {
             "qst_id":"csn1",
             "qst_title":"Very organized and always prepared"
          },
          {
             "qst_id":"ext1",
             "qst_title":"The life of party"
          },
          {
             "qst_id":"agg1",
             "qst_title":"Have a soft heart"
          },
          {
             "qst_id":"neu1",
             "qst_title":"Got stressed out easily"
          },
          {
             "qst_id":"opn2",
             "qst_title":"Full of ideas"
          },
          {
             "qst_id":"csn2",
             "qst_title":"Always pay attention to details"
          },
          {
             "qst_id":"ext2",
             "qst_title":"Feel comfortable around people"
          },
          {
             "qst_id":"agg2",
             "qst_title":"Intrested in people"
          },
          {
             "qst_id":"neu2",
             "qst_title":"Relaxed most of the time"
          },
          {
             "qst_id":"opn3",
             "qst_title":"Do not have a good imagination"
          },
          {
             "qst_id":"csn3",
             "qst_title":"Procrastinate too much"
          },
          {
             "qst_id":"ext3",
             "qst_title":"Do not talk a lot"
          },
          {
             "qst_id":"agg3",
             "qst_title":"Not really interested in other people's problems"
          },
          {
             "qst_id":"neu3",
             "qst_title":"Seldom feel blue"
          },
          {
             "qst_id":"opn4",
             "qst_title":"Have difficulty understanding abstract ideas"
          },
          {
             "qst_id":"csn4",
             "qst_title":"Tend to make a mess of things"
          },
          {
             "qst_id":"ext4",
             "qst_title":"Quite around strangers"
          },
          {
             "qst_id":"agg4",
             "qst_title":"Feel little concern for others"
          },
          {
             "qst_id":"neu4",
             "qst_title":"Have frequent mood swings"
          }
       ]
    
    

    在反应组件中

    questions.map(question=> 
    <>
       <div className="form-check form-check-inline">
              <input
                onChange={e=>{
                    handleAnswerAdd(question.qst_id, e.target.value);
                }}
                name={question.qst_id}
                className="form-check-input"
                type="radio"
                id={question.qst_id}
                value={answers[question.qst_id]}
              />
              <label className="form-check-label" htmlFor="inlineCheckbox5">
                {
                  // Change this to what you want here. not quite sure
                  answers[question.qst_id] 
                } 
              </label>
            </div>
            <h4>{question.qst_title}</h4>
    </>
    );
    

    【讨论】:

    • 您好 Jayaram Kasi,感谢您的回答,但它无法正常工作。它不会将选定的单选值添加到结果状态。
    【解决方案2】:

    Jayaram Kasi 的回答几乎是完美的。我对 handleAnswerAdd 函数做了一个小改动,现在它将选择的单选按钮值添加到结果状态。

    const handleAnswerAdd = (questionKey, answer) => (setResult({
        ...result,
        [questionKey]: answer
     })); 
      if (data) {
        return (
          <form className="container shadow-lg">
            <h1>I am someone who...</h1>
    
            {questions.map((question) => (
              <div key={question.qst_id}>
                <p>{question.qst_title}</p>
    
                <div className="form-check form-check-inline">
                  <input
                    onChange={(e) => {
                      handleAnswerAdd(question.qst_id, e.target.value);
                    }}
                    name={question.qst_id}
                    className="form-check-input"
                    type="radio"
                    id={question.qst_id}
                    value={answers[index].answ_id}
                  />
                  <label className="form-check-label" htmlFor="inlineCheckbox5">
                    1
                  </label>
                </div>
                <div className="form-check form-check-inline">
                  <input
                    onChange={(e) => {
                      handleAnswerAdd(question.qst_id, e.target.value);
                    }}
                    name={question.qst_id}
                    className="form-check-input"
                    type="radio"
                    id={question.qst_id}
                    value={answers[index + 1].answ_id}
                  />
                  <label className="form-check-label " htmlFor="inlineCheckbox5">
                    2
                  </label>
                </div>
                <div className="form-check form-check-inline">
                  <input
                    onChange={(e) => {
                      handleAnswerAdd(question.qst_id, e.target.value);
                    }}
                    name={question.qst_id}
                    className="form-check-input"
                    type="radio"
                    id={question.qst_id}
                    value={answers[index + 2].answ_id}
                  />
                  <label className="form-check-label " htmlFor="inlineCheckbox5">
                    3
                  </label>
                </div>
                <div className="form-check form-check-inline">
                  <input
                    onChange={(e) => {
                      handleAnswerAdd(question.qst_id, e.target.value);
                    }}
                    name={question.qst_id}
                    className="form-check-input"
                    type="radio"
                    id={question.qst_id}
                    value={answers[index + 3].answ_id}
                  />
                  <label className="form-check-label " htmlFor="inlineCheckbox5">
                    4
                  </label>
                </div>
                <div className="form-check form-check-inline">
                  <input
                    onChange={(e) => {
                      handleAnswerAdd(question.qst_id, e.target.value);
                    }}
                    name={question.qst_id}
                    className="form-check-input"
                    type="radio"
                    id={question.qst_id}
                    value={answers[index + 4].answ_id}
                  />
                  <label className="form-check-label " htmlFor="inlineCheckbox5">
                    5
                  </label>
                </div>
              </div>
            ))}
            <button onClick={onStoreAnswers}>Next Page</button>
          </form>
        );
      }
    

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-12
      • 1970-01-01
      • 2020-01-26
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      • 2019-12-11
      • 2015-02-21
      相关资源
      最近更新 更多