izzy
izzy

Reputation: 95

Why are the elements from a mapping function not rendering?

  1. Summarize the problem
  1. Describe what you've tried
  1. Show some code

here is Provider.js

import React, { useState, useEffect } from 'react';
import he from 'he';

export const myContext = React.createContext();

const Provider = props => {
    const [state, setState] = useState({
        loading: true,
        error: false,
        data: [],
    });
    const [page, setPage] = useState(1);
    const [score, setScore] = useState(0);
    const [correctAnswers, setCorrectAnswers] = useState([]);
    const [allQuestions, setAllQuestions] = useState([]);
    const [answers, setAnswers] = useState([]);
    const [right, setRight] = useState([]);
    const [wrong, setWrong] = useState([]);
    function clearScore() {
      updatedScore = 0;
    }
    function clearRights() {
      while (rights.length > 0) {
        rights.pop();
      }
    }
    function clearWrongs() {
      while (wrongs.length > 0) {
        wrongs.pop();
      }
    }
    let updatedScore = 0;
    let rights = [];
    let wrongs = [];
    const calcScore = (x, y) => {
      for (let i = 0; i < 10; i++) {
        if (x[i] === y[i]) {
          updatedScore = updatedScore + 1;
          rights.push(i);
        } else wrongs.push(i);
    }
}
    useEffect(() => {
        fetch('https://opentdb.com/api.php?amount=10&difficulty=hard&type=boolean')
          .then(response => {
            return response.json()
          })
          .then(json => {
            const correctAnswer = json.results.map(q => q['correct_answer']);
            const questionBulk = json.results.map(q => q['question']);
            setState({
              data: json.results,
              loading: false,
              error: false,
            });
            setCorrectAnswers(correctAnswers.concat(correctAnswer));
            setAllQuestions(allQuestions.concat(questionBulk));
          })
          .catch(err => {
            setState({error: err})
          })
    }, [])
    return (
        <myContext.Provider
            value={{
              state, page, score, answers, right, wrong,
              hitTrue: () => {setAnswers(answers.concat('True')); setPage(page + 1);},
              hitFalse: () => {setAnswers(answers.concat('False')); setPage(page + 1);},
              resetAll: () => {
                setAnswers([]);
                setPage(1);
                setScore(0);
                setRight([]);
                setWrong([]);
                clearScore();
                clearWrongs();
                clearRights();
              },
              calculateScore: () => calcScore(answers, correctAnswers),
              updateScore: () => setScore(score + updatedScore),
              updateRight: () => setRight(right.concat(rights)),
              updateWrong: () => setWrong(wrong.concat(wrongs)),
              showRightAnswers: () => {right.map((result, index) => {
                return (
                  <p className="text-green-300 text-sm" key={index}>
                    + {he.decode(`${allQuestions[result]}`)}
                  </p>)
              })},
              showWrongAnswers: () => {wrong.map((result, index) => {
                return (
                  <p className="text-red-500 text-sm" key={index}>
                    - {he.decode(`${allQuestions[result]}`)}
                  </p>
                )
              })},
            }}
        >
            {props.children}
        </myContext.Provider>
    );
}

export default ({ element }) => (
    <Provider>
        {element}
    </Provider>
);

^the showRightAnswers() and showWrongAnswers() methods are the ones I am trying to figure out

and here is the results.js page.{context.showRightAnswers()} and {context.showWrongAnswers()} are where the mapped content is supposed to appear.

import React from 'react';
import Button from '../components/Button';
import { navigate } from 'gatsby';
import { myContext } from '../hooks/Provider';

const ResultsPage = () => {
    return (
        <myContext.Consumer>
            {context => (
                <>
                    <h1 className="">You Finished!</h1>
                    <p className="">Your score was {context.score}/10</p>
                        {context.showRightAnswers()}
                        {context.showWrongAnswers()}
                    <Button
                        buttonText="Try Again?"
                        buttonActions={() => {
                            context.resetAll();
                            navigate('/');
                        }}
                    />
                </>
            )}
        </myContext.Consumer>
    );
}

export default ResultsPage;

Upvotes: 1

Views: 47

Answers (1)

Jayce444
Jayce444

Reputation: 9073

You are returning inside your map, but you're not returning the map call itself - .map returns an array, and you have to return that array from your "show" functions, e.g.

showWrongAnswers: () => { return wrong.map((result, index) ...
                           ^^^^

This will return the array .map generated from the showWrongAnswers function when it's called, and thus {context.showWrongAnswers()} will render that returned array

Upvotes: 3

Related Questions