获取数组 useState React 中的下一个对象
Get next object in Array useState React
我正在构建一个测验网站作为 React 的练习,并希望能够通过按钮更改问题。当我手动将 useState(0) 更改为 1 时,下一个对象将呈现。但我无法让它与按钮一起工作。当我单击按钮时,它会直接跳转到警报消息。
function GetMovies() {
useEffect(() => {
fetchItems();
}, []);
const [items, setItems] = useState({ options: [] });
const fetchItems = async () => {
const data = await fetch("http://localhost:5000/api/movies");
const items = await data.json();
//test
//console.log(items[currentQuestion]);
setItems(items[currentQuestion]);
};
const [currentQuestion, setCurrentQuestion] = useState(0);
//change question solution that dont work
const HandleAnswerButtonClick = () => {
const nextQuestion = setCurrentQuestion + 1;
if (nextQuestion < items.length) {
setCurrentQuestion(nextQuestion);
} else {
alert("End of quiz");
}
setCurrentQuestion(nextQuestion);
};
return (
<div className="App">
<h1>Quiza</h1>
<div>
<span>Question 1</span>
</div>
<div>
<h3>Question: {items.description}</h3>
{items.options.map((c) => (
<button value={c.is_correct} key={c.text}>
{c.text}
</button>
))}
<div>
{//Next BUTTON}
<button onClick={() => HandleAnswerButtonClick()}>
Next question
</button>
</div>
{/* if-sats, om bild finns till frågan visas den, annars en class med display none */}
<div className="Q_pics">
{items.options.map((c) =>
!c.image ? (
<p className="Display_none">empty</p>
) : (
<img src={c.image} alt={c.text}></img>
)
)}
</div>
</div>
</div>
);
}
来自我的 API
的猫鼬模式
const MovieSchema = mongoose.Schema(
{
category: { type: String, required: true },
description: { type: String, required: true },
image: {
type: String,
required: false,
},
options: [
{
text: {
type: String,
required: true,
},
is_correct: {
type: Boolean,
required: true,
default: false,
},
image: {
type: String,
required: false,
},
},
],
},
{ collection: "movies" }
);
那是因为
const nextQuestion = setCurrentQuestion + 1;
应该是
const nextQuestion = currentQuestion + 1;
哦,正如@Nick Parsons 在评论中提到的,您也只将第一个问题存储在您的状态中,因为 fetchItems
只有 运行 一次,而您 setItems(items[currentQuestion]);
你应该这样做
function GetMovies() {
const [items, setItems] = useState([]);
const [currentQuestion, setCurrentQuestion] = useState(0);
const fetchItems = async () => {
const data = await fetch("http://localhost:5000/api/movies");
const items = await data.json();
//test
//console.log(items[currentQuestion]);
setItems(items);
};
//change question solution that dont work
const HandleAnswerButtonClick = () => {
const nextQuestion = currentQuestion + 1;
if (nextQuestion < items.length) {
setCurrentQuestion(nextQuestion);
} else {
alert("End of quiz");
}
setCurrentQuestion(nextQuestion);
};
useEffect(() => {
fetchItems();
}, []);
const activeQuestion = items[currentQuestion];
return (
<div className="App">
<h1>Quiza</h1>
<div>
<span>Question {currentQuestion + 1}</span>
</div>
<div>
<h3>Question: {activeQuestion && activeQuestion.description}</h3>
{activeQuestion && activeQuestion.options.map((c) => (
<button value={c.is_correct} key={c.text}>
{c.text}
</button>
))}
<div>
{//Next BUTTON}
<button onClick={() => HandleAnswerButtonClick()}>
Next question
</button>
</div>
{/* if-sats, om bild finns till frågan visas den, annars en class med display none */}
<div className="Q_pics">
{activeQuestion && activeQuestion.options.map((c) =>
!c.image ? (
<p className="Display_none">empty</p>
) : (
<img src={c.image} alt={c.text}></img>
)
)}
</div>
</div>
</div>
);
}
代码可能是这样的:
const [items, setItems] = useState({ options: [] });
// currentIdx might be a better name
const [currentIdx, setCurrentIdx] = useState(0);
const fetchItems = async () => {
const data = await fetch("http://localhost:5000/api/movies");
const items = await data.json();
// save all data as Nick said. and items should be type of Data[];
setItems(items);
};
const HandleAnswerButtonClick = () => {
const nextQuestion = currentIdx + 1;
if (nextQuestion < items.length) {
setCurrentIdx(nextQuestion);
} else {
alert("End of quiz");
}
};
// use displayItem for render
const displayItem = useMemo(() => items[currentIdx], [items, currentIdx]);
我认为你最好学会使用开发工具并观察代码的价值
我正在构建一个测验网站作为 React 的练习,并希望能够通过按钮更改问题。当我手动将 useState(0) 更改为 1 时,下一个对象将呈现。但我无法让它与按钮一起工作。当我单击按钮时,它会直接跳转到警报消息。
function GetMovies() {
useEffect(() => {
fetchItems();
}, []);
const [items, setItems] = useState({ options: [] });
const fetchItems = async () => {
const data = await fetch("http://localhost:5000/api/movies");
const items = await data.json();
//test
//console.log(items[currentQuestion]);
setItems(items[currentQuestion]);
};
const [currentQuestion, setCurrentQuestion] = useState(0);
//change question solution that dont work
const HandleAnswerButtonClick = () => {
const nextQuestion = setCurrentQuestion + 1;
if (nextQuestion < items.length) {
setCurrentQuestion(nextQuestion);
} else {
alert("End of quiz");
}
setCurrentQuestion(nextQuestion);
};
return (
<div className="App">
<h1>Quiza</h1>
<div>
<span>Question 1</span>
</div>
<div>
<h3>Question: {items.description}</h3>
{items.options.map((c) => (
<button value={c.is_correct} key={c.text}>
{c.text}
</button>
))}
<div>
{//Next BUTTON}
<button onClick={() => HandleAnswerButtonClick()}>
Next question
</button>
</div>
{/* if-sats, om bild finns till frågan visas den, annars en class med display none */}
<div className="Q_pics">
{items.options.map((c) =>
!c.image ? (
<p className="Display_none">empty</p>
) : (
<img src={c.image} alt={c.text}></img>
)
)}
</div>
</div>
</div>
);
}
来自我的 API
的猫鼬模式const MovieSchema = mongoose.Schema(
{
category: { type: String, required: true },
description: { type: String, required: true },
image: {
type: String,
required: false,
},
options: [
{
text: {
type: String,
required: true,
},
is_correct: {
type: Boolean,
required: true,
default: false,
},
image: {
type: String,
required: false,
},
},
],
},
{ collection: "movies" }
);
那是因为
const nextQuestion = setCurrentQuestion + 1;
应该是
const nextQuestion = currentQuestion + 1;
哦,正如@Nick Parsons 在评论中提到的,您也只将第一个问题存储在您的状态中,因为 fetchItems
只有 运行 一次,而您 setItems(items[currentQuestion]);
你应该这样做
function GetMovies() {
const [items, setItems] = useState([]);
const [currentQuestion, setCurrentQuestion] = useState(0);
const fetchItems = async () => {
const data = await fetch("http://localhost:5000/api/movies");
const items = await data.json();
//test
//console.log(items[currentQuestion]);
setItems(items);
};
//change question solution that dont work
const HandleAnswerButtonClick = () => {
const nextQuestion = currentQuestion + 1;
if (nextQuestion < items.length) {
setCurrentQuestion(nextQuestion);
} else {
alert("End of quiz");
}
setCurrentQuestion(nextQuestion);
};
useEffect(() => {
fetchItems();
}, []);
const activeQuestion = items[currentQuestion];
return (
<div className="App">
<h1>Quiza</h1>
<div>
<span>Question {currentQuestion + 1}</span>
</div>
<div>
<h3>Question: {activeQuestion && activeQuestion.description}</h3>
{activeQuestion && activeQuestion.options.map((c) => (
<button value={c.is_correct} key={c.text}>
{c.text}
</button>
))}
<div>
{//Next BUTTON}
<button onClick={() => HandleAnswerButtonClick()}>
Next question
</button>
</div>
{/* if-sats, om bild finns till frågan visas den, annars en class med display none */}
<div className="Q_pics">
{activeQuestion && activeQuestion.options.map((c) =>
!c.image ? (
<p className="Display_none">empty</p>
) : (
<img src={c.image} alt={c.text}></img>
)
)}
</div>
</div>
</div>
);
}
代码可能是这样的:
const [items, setItems] = useState({ options: [] });
// currentIdx might be a better name
const [currentIdx, setCurrentIdx] = useState(0);
const fetchItems = async () => {
const data = await fetch("http://localhost:5000/api/movies");
const items = await data.json();
// save all data as Nick said. and items should be type of Data[];
setItems(items);
};
const HandleAnswerButtonClick = () => {
const nextQuestion = currentIdx + 1;
if (nextQuestion < items.length) {
setCurrentIdx(nextQuestion);
} else {
alert("End of quiz");
}
};
// use displayItem for render
const displayItem = useMemo(() => items[currentIdx], [items, currentIdx]);
我认为你最好学会使用开发工具并观察代码的价值