Как создать функцию в Reactjs, которая не вызывается прослушивателем событий?

Я новичок в 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 он не делает ничего, кроме отображения вопросов.

почему вы хотите вызвать selectionQues? Вы хотите отобразить вопросы викторины? пожалуйста, чего вы хотите добиться.

Abu Sufian 23.12.2020 15:27

@Мариум: АсаламуАЛыкум! Что именно вы подразумеваете под словом "вопрос"? Не могли бы вы уточнить. Я считаю, что в useEffect() мы можем достичь того, что вы ищете, но уточните, чего вы хотите достичь? Спасибо

Imran Rafiq Rather 23.12.2020 15:29
But i want it to be executed after the first useEffect has been called -- вы можете вызвать его внутри обратного вызова useEffect и сохранить некоторое состояние, чтобы вы не могли вызвать его снова
TKoL 23.12.2020 15:30

@AbuSufian Привет! поэтому я хочу отображать 5 запросов за раз, поэтому я случайным образом выбираю эти запросы, поскольку API содержит 20 вопросов. поэтому я создал новое состояние, в котором хранятся эти 5 вопросов.

Marium Ali 23.12.2020 15:33

поэтому, если я правильно понимаю, вы хотите вызвать его после успешного запроса API

Chandan 23.12.2020 15:34

@ImranRafiqRather Ваалейкумсалам. Плохо, что я напечатал это неправильно, это был вызов функции selectionQuestion(). Я отредактировал это сейчас

Marium Ali 23.12.2020 15:34

вы можете добавить еще один useEffect, который может проверять обновление состояния curr, если оно делится на 5, тогда вы можете вызвать selectingQues

Chandan 23.12.2020 15:37

Возможно ли, что это сценарий, в котором ваша работа будет упрощена, если вы перестанете пытаться использовать функциональный компонент со всеми этими useState и useEffect вещами, а вместо этого просто будете использовать компонент с отслеживанием состояния? Я чувствую, что люди иногда прилагают много ненужных усилий для поддержания работоспособности компонентов, хотя для этого не всегда есть веская причина.

TKoL 23.12.2020 15:40

@TKoL Думаю, я попробую одно из твоих решений. Спасибо

Marium Ali 23.12.2020 15:44

@MariumAli: придумали решение вашей проблемы. Это прямо вперед. Если у вас есть какие-либо вопросы, дайте мне знать :)

Imran Rafiq Rather 23.12.2020 16:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
10
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ИДЕЯ: Основная идея состоит в том, чтобы получить наш массив вопросов в нашем вызове API и убедиться, что там есть случайные 5 вопросов. Как я это делаю, как только я получаю свои данные из моего вызова API, я делаю promise chaining и обрабатываю весь свой код, чтобы получить 5 случайных вопросов в этом другом then() блоке. Когда я получаю свои 5 случайных вопросов, я сохраняю в состоянии currentQues.

Демо Codesandbox

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: это рабочий код для вас. Проголосуйте и примите ответ, если этот ответ вам полезен. Это поможет и другим вопрошающим. Спасибо :)

Imran Rafiq Rather 23.12.2020 17:06

Большое спасибо! Так что в основном моя идея была в порядке, но мое исполнение было неправильным :). Вы очень помогли, спасибо!!

Marium Ali 01.01.2021 09:16

AnyTime :) Добро пожаловать :) Да, ваша идея была правильной, чтобы сначала получить данные и получить 5 случайных вопросов оттуда же. Так держать !!!

Imran Rafiq Rather 01.01.2021 09:18

Другие вопросы по теме