React - 将答案显示为列表
React - display answer as a list
我正在创建一个 React 测验应用程序,但我正在尝试弄清楚如何让我的答案数组显示为列表。到目前为止,这是我的代码
加载数据成功地从 api 加载数据,当我在我的答案变量上进行控制台登录时,我可以看到每个问题的数组都有四个正确的答案。
const loadData = async () => {
let response = await fetch(
"https://opentdb.com/api.php?amount=10&category=22&difficulty=medium&type=multiple"
);
const data = await response?.json();
console.log(data);
const getQuestions = data.results.map((item) => {
const question = item.question;
const answers = [...item.incorrect_answers, item.correct_answer];
//console.log(answers) shows this as an example
["Quebec", "Ontario", "Nova Scotia", "Alberta"]
return {
question: question,
answers: answers,
};
});
return getQuestions;
};
function App() {
//create useState hook to pass data into
const [showData, setData] = useState([]);
//pass the data into a useeffect hook and setData to the loadData method from above
useEffect(() => {
(async () => {
const getData = await loadData();
setData(getData);
})();
}, []);
return (
<React.Fragment>
{showData.map((data) => (
<>
<div>
<h1>{data.question}</h1>
<ul>{data.answers}</ul>
</div>
</>
))}
</React.Fragment>
);
}
return 函数输出问题,但如果我尝试将答案显示为列表以便我可以单独获取每个答案,它只会将它们放在同一行。
例如:
瑞士的首都是哪个城市?api
苏黎世、法兰克福、维也纳、伯尔尼
任何帮助将不胜感激:)
您可以使用另一个 map
:
遍历 answers
数组
<ul>
{
data.answers.map((answer) =>
// It's a good practice to apply a unique identifier as key to your list
// Not the index, however, as it may change
<li key={someValue}>answer</li>
)
}
</ul>
您应该迭代答案数组而不是直接渲染它们。
ul 也是无序列表的 parent 标签,你应该使用 li 列出 children.
import { useEffect, useState } from "react";
export default function App() {
const [showData, setData] = useState([]);
const loadData = async () => {
let response = await fetch(
"https://opentdb.com/api.php?amount=10&category=22&difficulty=medium&type=multiple"
);
const data = await response?.json();
console.log(data);
const getQuestions = data.results.map((item) => {
const question = item.question;
const answers = [...item.incorrect_answers, item.correct_answer];
return {
question: question,
answers: answers
};
});
return getQuestions;
};
useEffect(() => {
(async () => {
const getData = await loadData();
setData(getData);
})();
}, []);
return (
<>
{showData.map((data,i) => (
<>
<div key={i}>
<h4>{data.question}</h4>
// map the answers separately
{data.answers.map((item,j)=><li key={j}>{item}</li>)}
</div>
</>
))}
</>
);
}
在此处检查代码:https://codesandbox.io/s/floral-leftpad-zcwew?file=/src/App.js:0-1063
试试这个 ♂️
function App() {
//create useState hook to pass data into
const [showData, setData] = useState([]);
//pass the data into a useeffect hook and setData to the loadData method from above
useEffect(() => {
(async () => {
const getData = await loadData();
setData(getData);
})();
}, []);
return (
<React.Fragment>
{showData.map((data, index) => {
return (
<div key={index}>
<div>
<h1>{data.question}</h1>
<ul>
{data.answers.map((answer, index) => {
return (
<li key={index}>{answer}</li>
)
})}
</ul>
</div>
</div>
);
})}
</React.Fragment>
);
}
export default App;
这里有多个问题:
<ul>{data.answers}</ul>
将不起作用,因为 data.answers
是一个数组。您需要将此数组的元素映射到 <li>
元素,就像您在父元素中所做的那样。
- 无论何时使用
map
创建列表,都必须在每个元素上添加一个唯一键,通常是一个 id。我假设问题和答案是唯一的,因此您可以使用数据本身作为键。
- 您的代码在访问
response.json()
之前未检查 response.ok
。是的,您确实在此处使用了问号运算符,以便特定操作是安全的,但随后下一行的 undefined.results
崩溃了,因此它只会推波助澜并进一步混淆 fetch
错误。
- 删除多余的片段
<>
。
- 在 es6 中,
{questions: questions}
可以是 {questions}
.
- 当您继续使用该应用程序时,请不要忘记随机排列您的答案。
<script type="text/babel" defer>
const {Fragment, useEffect, useState} = React;
const loadData = async (
url="https://opentdb.com/api.php?amount=10&category=22&difficulty=medium&type=multiple"
) => {
const response = await fetch(url);
if (!response.ok) {
throw Error(response.status);
}
return (await response.json()).results.map(
({question, incorrect_answers, correct_answer}) => ({
question,
answers: [...incorrect_answers, correct_answer]
})
);
};
const App = () => {
const [data, setData] = useState([]);
useEffect(() => {
loadData()
.then(setData)
.catch(err => console.error(err))
;
}, []);
return (
<Fragment>
{data.map(({question, answers}) => (
<div key={question}>
<h3>{question}</h3>
<ul>
{answers.map(a => <li key={a}>{a}</li>)}
</ul>
</div>
))}
</Fragment>
);
}
ReactDOM.render(<App />, document.body);
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
我正在创建一个 React 测验应用程序,但我正在尝试弄清楚如何让我的答案数组显示为列表。到目前为止,这是我的代码
加载数据成功地从 api 加载数据,当我在我的答案变量上进行控制台登录时,我可以看到每个问题的数组都有四个正确的答案。
const loadData = async () => {
let response = await fetch(
"https://opentdb.com/api.php?amount=10&category=22&difficulty=medium&type=multiple"
);
const data = await response?.json();
console.log(data);
const getQuestions = data.results.map((item) => {
const question = item.question;
const answers = [...item.incorrect_answers, item.correct_answer];
//console.log(answers) shows this as an example
["Quebec", "Ontario", "Nova Scotia", "Alberta"]
return {
question: question,
answers: answers,
};
});
return getQuestions;
};
function App() {
//create useState hook to pass data into
const [showData, setData] = useState([]);
//pass the data into a useeffect hook and setData to the loadData method from above
useEffect(() => {
(async () => {
const getData = await loadData();
setData(getData);
})();
}, []);
return (
<React.Fragment>
{showData.map((data) => (
<>
<div>
<h1>{data.question}</h1>
<ul>{data.answers}</ul>
</div>
</>
))}
</React.Fragment>
);
}
return 函数输出问题,但如果我尝试将答案显示为列表以便我可以单独获取每个答案,它只会将它们放在同一行。
例如: 瑞士的首都是哪个城市?api 苏黎世、法兰克福、维也纳、伯尔尼
任何帮助将不胜感激:)
您可以使用另一个 map
:
answers
数组
<ul>
{
data.answers.map((answer) =>
// It's a good practice to apply a unique identifier as key to your list
// Not the index, however, as it may change
<li key={someValue}>answer</li>
)
}
</ul>
您应该迭代答案数组而不是直接渲染它们。 ul 也是无序列表的 parent 标签,你应该使用 li 列出 children.
import { useEffect, useState } from "react";
export default function App() {
const [showData, setData] = useState([]);
const loadData = async () => {
let response = await fetch(
"https://opentdb.com/api.php?amount=10&category=22&difficulty=medium&type=multiple"
);
const data = await response?.json();
console.log(data);
const getQuestions = data.results.map((item) => {
const question = item.question;
const answers = [...item.incorrect_answers, item.correct_answer];
return {
question: question,
answers: answers
};
});
return getQuestions;
};
useEffect(() => {
(async () => {
const getData = await loadData();
setData(getData);
})();
}, []);
return (
<>
{showData.map((data,i) => (
<>
<div key={i}>
<h4>{data.question}</h4>
// map the answers separately
{data.answers.map((item,j)=><li key={j}>{item}</li>)}
</div>
</>
))}
</>
);
}
在此处检查代码:https://codesandbox.io/s/floral-leftpad-zcwew?file=/src/App.js:0-1063
试试这个 ♂️
function App() {
//create useState hook to pass data into
const [showData, setData] = useState([]);
//pass the data into a useeffect hook and setData to the loadData method from above
useEffect(() => {
(async () => {
const getData = await loadData();
setData(getData);
})();
}, []);
return (
<React.Fragment>
{showData.map((data, index) => {
return (
<div key={index}>
<div>
<h1>{data.question}</h1>
<ul>
{data.answers.map((answer, index) => {
return (
<li key={index}>{answer}</li>
)
})}
</ul>
</div>
</div>
);
})}
</React.Fragment>
);
}
export default App;
这里有多个问题:
<ul>{data.answers}</ul>
将不起作用,因为data.answers
是一个数组。您需要将此数组的元素映射到<li>
元素,就像您在父元素中所做的那样。- 无论何时使用
map
创建列表,都必须在每个元素上添加一个唯一键,通常是一个 id。我假设问题和答案是唯一的,因此您可以使用数据本身作为键。 - 您的代码在访问
response.json()
之前未检查response.ok
。是的,您确实在此处使用了问号运算符,以便特定操作是安全的,但随后下一行的undefined.results
崩溃了,因此它只会推波助澜并进一步混淆fetch
错误。 - 删除多余的片段
<>
。 - 在 es6 中,
{questions: questions}
可以是{questions}
. - 当您继续使用该应用程序时,请不要忘记随机排列您的答案。
<script type="text/babel" defer>
const {Fragment, useEffect, useState} = React;
const loadData = async (
url="https://opentdb.com/api.php?amount=10&category=22&difficulty=medium&type=multiple"
) => {
const response = await fetch(url);
if (!response.ok) {
throw Error(response.status);
}
return (await response.json()).results.map(
({question, incorrect_answers, correct_answer}) => ({
question,
answers: [...incorrect_answers, correct_answer]
})
);
};
const App = () => {
const [data, setData] = useState([]);
useEffect(() => {
loadData()
.then(setData)
.catch(err => console.error(err))
;
}, []);
return (
<Fragment>
{data.map(({question, answers}) => (
<div key={question}>
<h3>{question}</h3>
<ul>
{answers.map(a => <li key={a}>{a}</li>)}
</ul>
</div>
))}
</Fragment>
);
}
ReactDOM.render(<App />, document.body);
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>