Я новичок в ReactJS и пытаюсь создать простое приложение для викторины. То, что я хочу сделать, можно увидеть в функции selectionQues().
import React,{useState,useEffect} from 'react';
import './App.css';
import Question from './components/Question';
function App() {
const [ques, setques] = useState([]);
const [currentQues, setcurrentQues] = useState([]);
//importing ques using api
useEffect(() =>{
fetch('https://opentdb.com/api.php?amount=20&category=18&difficulty=medium&type=multiple')
.then((res)=> res.json())
.then((question) => {
setques(question.results);
});
},[setques])
//selecting 5 ques at random for our quiz
const selectingQues = () => {
let curr=[];
let qlen=ques.length;
for(let i=0;i<5;i++){
let selector= Math.floor(Math.random()*qlen);
curr[i]=ques[selector];
}
setcurrentQues(curr);
// console.info(ques);
}
return (
<div className = "App">
<Question currentQues = {currentQues}/>
</div>
);
}
export default App;
Теперь я хочу вызвать этот SelectingQues() без явного использования слушателя onClick или чего-то подобного. Возможно ли это с помощью useEffect? Но я хочу, чтобы он выполнялся после первого вызова useEffect.
Компонент вопроса не прикреплен, так как rn он не делает ничего, кроме отображения вопросов.
@Мариум: АсаламуАЛыкум! Что именно вы подразумеваете под словом "вопрос"? Не могли бы вы уточнить. Я считаю, что в useEffect() мы можем достичь того, что вы ищете, но уточните, чего вы хотите достичь? Спасибо
But i want it to be executed after the first useEffect has been called
-- вы можете вызвать его внутри обратного вызова useEffect
и сохранить некоторое состояние, чтобы вы не могли вызвать его снова
@AbuSufian Привет! поэтому я хочу отображать 5 запросов за раз, поэтому я случайным образом выбираю эти запросы, поскольку API содержит 20 вопросов. поэтому я создал новое состояние, в котором хранятся эти 5 вопросов.
поэтому, если я правильно понимаю, вы хотите вызвать его после успешного запроса API
@ImranRafiqRather Ваалейкумсалам. Плохо, что я напечатал это неправильно, это был вызов функции selectionQuestion(). Я отредактировал это сейчас
вы можете добавить еще один useEffect
, который может проверять обновление состояния curr
, если оно делится на 5, тогда вы можете вызвать selectingQues
Возможно ли, что это сценарий, в котором ваша работа будет упрощена, если вы перестанете пытаться использовать функциональный компонент со всеми этими useState
и useEffect
вещами, а вместо этого просто будете использовать компонент с отслеживанием состояния? Я чувствую, что люди иногда прилагают много ненужных усилий для поддержания работоспособности компонентов, хотя для этого не всегда есть веская причина.
@TKoL Думаю, я попробую одно из твоих решений. Спасибо
@MariumAli: придумали решение вашей проблемы. Это прямо вперед. Если у вас есть какие-либо вопросы, дайте мне знать :)
ИДЕЯ: Основная идея состоит в том, чтобы получить наш массив вопросов в нашем вызове API и убедиться, что там есть случайные 5 вопросов. Как я это делаю, как только я получаю свои данные из моего вызова API, я делаю promise chaining
и обрабатываю весь свой код, чтобы получить 5 случайных вопросов в этом другом then()
блоке. Когда я получаю свои 5 случайных вопросов, я сохраняю в состоянии currentQues
.
import React, { useState, useEffect } from "react";
import "./App.css";
function App() {
const [currentQues, setcurrentQues] = useState([]);
//importing ques using api
useEffect(() => {
selectingQues();
}, []);
// selecting 5 ques at random for our quiz
const selectingQues = async () => {
const response = await fetch(
"https://opentdb.com/api.php?amount=20&category=18&difficulty=medium&type=multiple"
);
const data = await response.json();
console.info(data);
const initialQuestions = data.results;
let curr = [];
// console.info(initialQuestions.length);
let length = initialQuestions.length;
for (let i = 0; i < 5; i++) {
let selector = Math.floor(Math.random() * length);
curr[i] = initialQuestions[selector];
}
setcurrentQues(curr);
};
return (
<div className = "App">
{currentQues.length > 0 && <Question currentQuestions = {currentQues} />}
</div>
);
}
export default App;
const Question = ({ currentQuestions }) => {
// const { question, correct_answer } = question;
console.info(currentQuestions);
return (
<>
{currentQuestions.map((question) => (
<div key = {question.question}>
<p>
<strong>Question:</strong> {question.question}
</p>
<p>
<strong>Answer:</strong> {question["correct_answer"]}
</p>
</div>
))}
</>
);
};
@MariumAli: это рабочий код для вас. Проголосуйте и примите ответ, если этот ответ вам полезен. Это поможет и другим вопрошающим. Спасибо :)
Большое спасибо! Так что в основном моя идея была в порядке, но мое исполнение было неправильным :). Вы очень помогли, спасибо!!
AnyTime :) Добро пожаловать :) Да, ваша идея была правильной, чтобы сначала получить данные и получить 5 случайных вопросов оттуда же. Так держать !!!
почему вы хотите вызвать selectionQues? Вы хотите отобразить вопросы викторины? пожалуйста, чего вы хотите добиться.