使用 React 创建一个调查,但一直在寻找一种方法来根据某些回答提出问题
Creating a survey using React but stuck finding a way to have questions dependent on certain responses
我正在创建一个向用户提供调查的相对基本的网站。但是我现在 运行 陷入了死胡同,试图找到一种方法让下一个问题依赖于上一个问题的答案。到目前为止,我有一个包含大约 40 个问题的数组的单独页面,一个将每个问题与其文本和答案映射的组件,以及呈现它们的页面。
const questionArray = [
{
question: "how old are you?",
answers: [
"younger than 15",
"between 15 and 20",
"older than 20",
],
questionId: 1,
},
{
question: "are you a student?",
answers: ["yes", "no"],
questionId: 2,
},
{
question: "where do you live",
answers: ["QLD", "NSW", "VIC", "ACT", "NT", "TAS", "WA"],
questionId: 3,
},
];
const QuestionComponent = ({ question, options, selected }) => {
const [answer, setAnswer] = useState(options);
return (
<div>
{question}
{answer.map((text, index) => (
<button
key={index}
onClick={() => {
setAnswer([text]);
selected(text);
}}
>
{text}
</button>
))}
</div>
);
};
class QuestionPage extends Component {
state = {
questions: [],
};
getQs = () => {
this.setState({ questions: questionArray });
};
componentDidMount() {
this.getqs();
}
render() {
return (
<div>
{this.state.questions.map(
({ question, answers, questionId }) => (
<QuestionComponent
question={question}
options={answers}
key={questionId}
/>
),
)}
</div>
);
}
}
这个方法到目前为止基本上只是通过组件列出所有问题。我只是想不出如何改变它,而不是一开始就列出所有问题,而是根据以前的答案添加一个问题。例如,如果用户回答问题 1 时年龄小于 15 岁,则下一个问题将是问题 3。
如有任何帮助,我们将不胜感激!
您实际上想构建一个决策树来解决该问题,例如,您可以将所有问题都放在数组中并有一个 requireResponses[]
字段
例如:
const questionArray = [
{
question: "how old are you?",
answers: ['younger than 15', 'between 15 and 20', 'older than 20'],
questionId: 1
},
{
question: "are you a student?",
answers: ['yes', 'no'],
questionId: 2,
requireResponses: [{ questionId: 1, answer: 0 }],
},
{
question: "where do you live",
answers: ['QLD', 'NSW', 'VIC', 'ACT', 'NT', TAS', WA'],
questionId: 3,
requireResponses: [{ questionId: 1, answer: 1 }, { questionId: 2, answer: 1 }],
}
];
并将 questionId
与 requireResponses
进行比较。
你也可以看看that library谁可以帮助你开发你的应用程序。
开始时您的原始代码中存在一些语法错误。
我重构了一下:
- 问题不是状态的一部分;问题本身不应该改变。
- 答案现在存储在
QuestionPage
的状态中。
- 问题有一个可选的
condition
字段,这是一个 returns 是否应显示此问题的功能。
注意:以下是干编码,因此其中可能存在一些愚蠢的拼写错误等。
const questionArray = [
{
question: "how old are you?",
answers: [
"younger than 15",
"between 15 and 20",
"older than 20",
],
questionId: 1,
},
{
question: "are you a student?",
answers: ["yes", "no"],
questionId: 2,
condition: ({ answers }) => answers[1] != "older than 20",
},
{
question: "where do you live",
answers: ["QLD", "NSW", "VIC", "ACT", "NT", "TAS", "WA"],
questionId: 3,
},
];
const QuestionComponent = ({ question, answer, onSelect }) => {
const { question, answers } = question;
return (
<div>
{question}
{answers.map((text, index) => (
<button
key={index}
onClick={() => {
onSelect(text);
}}
>
{text}
</button>
))}
</div>
);
};
class QuestionPage extends Component {
state = {
answers: {},
};
render() {
const questions = questionArray.filter(q => {
if (!q.condition) {
// no condition set; always visible
return true;
}
return q.condition({ answers });
});
return (
<div>
{questions.map(question => (
<QuestionComponent
question={question}
answer={this.state.answers[question.questionId]}
key={question.questionId}
onSelect={answer => {
const answers = {
...this.state.answers,
[question.questionId]: answer,
};
this.setState({ answers });
}}
/>
))}
</div>
);
}
}
我正在创建一个向用户提供调查的相对基本的网站。但是我现在 运行 陷入了死胡同,试图找到一种方法让下一个问题依赖于上一个问题的答案。到目前为止,我有一个包含大约 40 个问题的数组的单独页面,一个将每个问题与其文本和答案映射的组件,以及呈现它们的页面。
const questionArray = [
{
question: "how old are you?",
answers: [
"younger than 15",
"between 15 and 20",
"older than 20",
],
questionId: 1,
},
{
question: "are you a student?",
answers: ["yes", "no"],
questionId: 2,
},
{
question: "where do you live",
answers: ["QLD", "NSW", "VIC", "ACT", "NT", "TAS", "WA"],
questionId: 3,
},
];
const QuestionComponent = ({ question, options, selected }) => {
const [answer, setAnswer] = useState(options);
return (
<div>
{question}
{answer.map((text, index) => (
<button
key={index}
onClick={() => {
setAnswer([text]);
selected(text);
}}
>
{text}
</button>
))}
</div>
);
};
class QuestionPage extends Component {
state = {
questions: [],
};
getQs = () => {
this.setState({ questions: questionArray });
};
componentDidMount() {
this.getqs();
}
render() {
return (
<div>
{this.state.questions.map(
({ question, answers, questionId }) => (
<QuestionComponent
question={question}
options={answers}
key={questionId}
/>
),
)}
</div>
);
}
}
这个方法到目前为止基本上只是通过组件列出所有问题。我只是想不出如何改变它,而不是一开始就列出所有问题,而是根据以前的答案添加一个问题。例如,如果用户回答问题 1 时年龄小于 15 岁,则下一个问题将是问题 3。
如有任何帮助,我们将不胜感激!
您实际上想构建一个决策树来解决该问题,例如,您可以将所有问题都放在数组中并有一个 requireResponses[]
字段
例如:
const questionArray = [
{
question: "how old are you?",
answers: ['younger than 15', 'between 15 and 20', 'older than 20'],
questionId: 1
},
{
question: "are you a student?",
answers: ['yes', 'no'],
questionId: 2,
requireResponses: [{ questionId: 1, answer: 0 }],
},
{
question: "where do you live",
answers: ['QLD', 'NSW', 'VIC', 'ACT', 'NT', TAS', WA'],
questionId: 3,
requireResponses: [{ questionId: 1, answer: 1 }, { questionId: 2, answer: 1 }],
}
];
并将 questionId
与 requireResponses
进行比较。
你也可以看看that library谁可以帮助你开发你的应用程序。
开始时您的原始代码中存在一些语法错误。
我重构了一下:
- 问题不是状态的一部分;问题本身不应该改变。
- 答案现在存储在
QuestionPage
的状态中。 - 问题有一个可选的
condition
字段,这是一个 returns 是否应显示此问题的功能。
注意:以下是干编码,因此其中可能存在一些愚蠢的拼写错误等。
const questionArray = [
{
question: "how old are you?",
answers: [
"younger than 15",
"between 15 and 20",
"older than 20",
],
questionId: 1,
},
{
question: "are you a student?",
answers: ["yes", "no"],
questionId: 2,
condition: ({ answers }) => answers[1] != "older than 20",
},
{
question: "where do you live",
answers: ["QLD", "NSW", "VIC", "ACT", "NT", "TAS", "WA"],
questionId: 3,
},
];
const QuestionComponent = ({ question, answer, onSelect }) => {
const { question, answers } = question;
return (
<div>
{question}
{answers.map((text, index) => (
<button
key={index}
onClick={() => {
onSelect(text);
}}
>
{text}
</button>
))}
</div>
);
};
class QuestionPage extends Component {
state = {
answers: {},
};
render() {
const questions = questionArray.filter(q => {
if (!q.condition) {
// no condition set; always visible
return true;
}
return q.condition({ answers });
});
return (
<div>
{questions.map(question => (
<QuestionComponent
question={question}
answer={this.state.answers[question.questionId]}
key={question.questionId}
onSelect={answer => {
const answers = {
...this.state.answers,
[question.questionId]: answer,
};
this.setState({ answers });
}}
/>
))}
</div>
);
}
}