questions in regard to global state/ structure of data flow

lets say i have a huge array of questions, answers, and a lot of oher data all organized into 30 questions in an object. i want this to basically be the main source of all data regarding rendered text on screen, the correct answer, and other things but most importantly in this case i want it to keep track of right and wrong answers so that later on at the end of the test the user can see a list of answers they got right or wrong. sort of like this:

    id: nanoid(),
    title: "Question One",
    correct:false,
    description: "Which is the odd one out?",
    answer:'C',
    category:'spatial',
    type:'MCphoto',
    word:false,
    questionPhoto:{
      id:nanoid(), value:'./photos/spatialOne.png'
    }, {
    id: nanoid(),
    title: "Question Two",
    correct:false,
    description: "Which is the even one out?",
    answer:'C',
    category:'spatial',
    type:'MCphoto',
    word:false,
    questionPhoto:{
      id:nanoid(), value:'./photos/spatialOne.png'
    }

i am making a somewhat basic test with react. the main problem i keep running into is that this array gets shuffled, the questions are randomized, then they are rendered on the screen primarily through the Question component. in other words the info being passed down from parent to child through props and prop drilling etc should include a record of what were answered right or wrong. after being passed a few times down with MAJOR prop drilling (which is getting messy) i am having problems getting the list of right and wrong questions to be recorded and stored and then available to parent components and NOT just children. the component at the end of my test will be called a but the problem is that structurally this component is rendered from the App component and therefore does NOT have access to the data thats been altered/updated in the Questions component. (refer to bottom of comment for app/component structure) the breakdown component that shows the final scores, what was right and wrong etc.... is NOT a child of the Questions component. i know this would typically be a time to use global state but how would i go about doing that? do you think that global state is the best approach whenever you are having problems passing data from child to parent? while i would like an answer to this particularly coding problem and i will show you more code... i am also wondering what people approach is to using redux, when to use it, and why i keep having problems with accessing data in my projects. i was reading about how redux isn't really common to use on personal projects but when i read about context it says that you can avoid prop drilling BUT the data STILL CAN ONLY be passed from parent to child, essentially not solving my problem here...my component that shows the score breakdown and lists questions answered right or wrong is NOT a child of the questions/test components therefore its unable to access the record of right and wrong scores etc. is this a structural problem in my projects? should ALL the data be passed down from the App component or a very higher level compoennt so its availabe to every component child? to me that seems like it would make the App.js file rather (or any higher level component) cluttered with so many hooks, prop drilling etc. how do i avoid this? im trying to write an action creator something like this:




export const correctScore=(isCorrect, questions)=>{
  return {
    type:'IS_CORRECT',
    payload:{
      isCorrect:isCorrect,
question:question
  }
}
}

here i am making an action creator where the iscorrect value is set to true if the person gets answer right, and thus altering the huge questions file shown at beginning of my post.. the second paramater it takes in is the question itself, so that globally the test can keep track of which question was answered right or wrong

and then a reducer something like this :

const INITIAL_STATE={
  isCorrect:null,
question:null
};

export const correctReducer=(state=INITIAL_STATE, action)=>{
  switch (action.type){
    case "IS_CORRECT":
    return {...state, isCorrect:action.payload.isCorrect, question:action.payload.question}

    default:
    return state
  }
}

in my project within the test part of project i have some logic that handles this state (obviously i wired it up to mapstate to props etc to make it availbe. but it still seems to be giving me problems... this the test part of the project. essentially where the state is being altered through the setScore reducer. BUT after this is altered (and it doesn't even seem to be altering it properly)

          props.correctScore(true, props.question) ****here i am passing true in to the action create and then the current question ****
          console.log(props)
          props.setScore(props.score+9)
          props.handleNextClick()
          reset()
        }

i guess my questions are do you think redux is the best apoproach to this project? it is over 2k lines of code at this point. and im constantly running into these situations where i can't pass props or pieces of data back UP to components being rendered in the App.js file.... if someone wants to see my code if that is easier... pretty new to asking questions ive been coding about a year but very new to react/redux and redux has been a bit of a headache for me

below is the App component so you can see how the project is structured. the ParentComponent is essentially the landing page of the app. you press a button on that page to "begin the test" and it leads u to the Question component. the question component is where all the data begins. it takes the data, does things with the data using QUITE few hooks. i will show you my questions component (or at least the logic for managing the questions object etc. ) i am not attaching the rendereed results because they are lengthy and not relevant here.

here is the question component. where all the data is recieved. note that the breakdown component is being rendered in the App component therefore it is NOT able to recieve any of the data, state, or manipulation of state with hooks BC the breakdown component isn't a child of the question component:

import React, {useState, useEffect} from 'react'
import Answers from './Answers'
import Range from './Range'
import QFIB from './QFIB'
import AFIB from './AFIB'
import './Question.css'
import {BrowserRouter as Router, Switch, Link, Route } from 'react-router-dom'
import {test, tester} from './utils/shuffler'

const qAndA=[{

}]

const Question =({score, setScore})=>{
  const [question, setQuestion]=useState('')
  const [questions, setQuestions]=useState(test)
  const [qIndex, setQIndex]=useState(0)
  const [answer, setAnswer]=useState('')
  const [id, setId]=useState('')
  const myRef=React.createRef()
  const [percentage, setPercentage]=useState(0)

useEffect(()=>{
  window.scrollTo(0, 0);

},[qIndex])

  const [random, setRandom]=useState(null)


  const handleAnswerChange=e=>{
    const currentQuestion=questions[qIndex]

    const answeredQuestion={
      ...currentQuestion,
      finalAnswer:e.target.value
    }
    const newQuestions=[...questions]
    newQuestions.splice(qIndex, 1, answeredQuestion);
    setQuestions(newQuestions);
  }
  let content=''
  const handleBackClick = () => setQIndex((i) => (i > 0 ? i - 1 : 0));
  const handleNextClick = () =>{
    setPercentage(percentage+(100/29))
    setQIndex((i) => (i < questions.length - 1 ? i + 1 : i));
  }



  const scoring=e=>{
    e.preventDefault()
  }

  const questionsAndAnswers=qAndA.map(questions=>{
    return {question:questions.question, id:questions.id, answer:questions.answer}
  })



Read more here: https://stackoverflow.com/questions/64948840/questions-in-regard-to-global-state-structure-of-data-flow

Content Attribution

This content was originally published by Robert O'Toole at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: