简体   繁体   中英

How to get answers from multiple components in ReactJS?

I'm working on a survey project, where I'm having a react component 'Questions', a child component 'QuestionOptions' with multiple children 'Radio', 'TextBox', 'Checkbox'. Some questions in the database have options (multiple choice). I want to find a way to gather all the answers answered by the user and send them to the database.

This is the Questions component:

const Questions = () => {
    const [questions, setQuestions] = useState([])
    var game_id = localStorage.getItem('game_id')

    useEffect(() => {
        axios
        .post("http://127.0.0.1:8000/api/v1/questions/get_questions", {
            game_id: game_id
        })
    
        .then((response) => {
            const s = response.data.questions;
            setQuestions(s);
        });
        }, []);

    return (
        <div>
            <ul>
                {questions.map((question) => (
                    <div key={question.id}>
                        <li key={question.id}>{question.question} ({question.points} points)</li>
                        <QuestionOptions question_id={question.id} question_type={question.question_type_id}/>
                    </div>
                ))}
            </ul>
            <Button text={"Submit"} id={"submit_btn"}/>
        </div>
    );
};

This is the QuestionOptions component:

const QuestionOptions = (props) => {
    const [options, setOptions] = useState([]);
    const question_type = props.question_type;
    useEffect(() => {
        axios
        .post("http://127.0.0.1:8000/api/v1/question_options/get_options", {
            question_id: props.question_id,
        })

        .then((response) => {
            setOptions(response.data["options"]);
        });
    }, [props.question_id]);


    if(question_type === 0){
        return(
            <TextBox />
        )
    }else if(question_type === 1){
        return(
            <Radio options={options}/>
        )
    }else if(question_type === 2){
        return(
            <Checkbox options={options}/>
        )
    }
};

The TextBox, Radio and Checkbox components looks as follows:

import React from "react";

const TextBox = () => {
  return <input type={"text"} />;
};

export default TextBox;

So I want to get all the answers answered by the user, and disable the submit button if not all questions are answered.

The Questions component looks as follows:

  1. What is your name? .(input goes here)

  2. What is your favorite color? . option1 . option2 . option3

What is the best way to make that happen?

Here is example with two types of questions: ones with a save button option, others which update answers directly. Check the output of console.log after you click save button or type answer in the third question.

let questions = [
  { q: 'How old are you?', id: 0 },
  { q: 'How many pets do you have?', id: 1 },
  { q: 'Where were you born?', id: 2, type: 'NoSaveBtn' },
];

let Question = (props) => {
  let [value, setValue] = React.useState('');
  return (
    <div>
      <div>{props.q}</div>
      <input value={value} onChange={(e) => setValue(e.target.value)}></input>
      <button
        onClick={() => {
          props.onSaveAnswer(value);
        }}
      >
        save answer
      </button>
    </div>
  );
};

let QuestionNoSaveBtn = (props) => {
  return (
    <div>
      <div>{props.q}</div>
      <input
        value={props.value || ''}
        onChange={(e) => props.onSaveAnswer(e.target.value)}
      ></input>
    </div>
  );
};
export default function App() {
  let [answers, setAnswers] = React.useState({});

  console.log(answers);
  return (
    <div>
      {questions.map((x) =>
        x.type !== 'NoSaveBtn' ? (
          <Question
            q={x.q}
            key={x.id}
            onSaveAnswer={(answer) =>
              setAnswers({ ...answers, [x.id]: answer })
            }
          />
        ) : (
          <QuestionNoSaveBtn
            q={x.q}
            key={x.id}
            value={answers[x.id]}
            onSaveAnswer={(answer) =>
              setAnswers({ ...answers, [x.id]: answer })
            }
          />
        )
      )}
    </div>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM