Search code examples
javascriptarraysreactjsuse-effectshuffle

Randomly order elements in an array Once in React (Possibly using Use effect)


I'm working on a solo project quizzical whilst learning react but cant find a solution to give the answers a random order without breaking my code. I have tried to use a shuffle function but this just causes the order of the answers to change with every click, I also tried to add the correct answer at a random index but the same problem happened. Not sure if I have to totally restructure my code or if there is a workaround. Be great if someone could take a look.

https://scrimba.com/learn/learnreact/fork-of-section-4-solo-project-coc8e46febb53e8d33018993e

As you can see all correct answers are in the last position in the answer array

I have attempted to use useEffect but really unsure if this is a situation where it should be used, this is just what i've left in my code. Removing the useEffect shuffles on every button click placing answers in the wrong places. I have included this code but may be hard to gauge the problem so scrim is attached

        const incorrectIds = [nanoid(), nanoid(), nanoid()]
        let counter = 0
            
        const correctAnswer = 
                                    <button 
                                            value='correct'
                                            id={correctId}
                                            onClick={e => {
                                                changeClass(correctId, 'correct')
                                                props.answerQuestion(e, 'correct')
                                            }}>       
                                    {props.result.correct_answer}</button>
                            
                                    
                
        let answers = props.result.incorrect_answers
        let allAnswers = answers.map(answer => {
                            const id = incorrectIds[counter]
                            counter++ 
                            return (
                            <button 
                                value='incorrect'
                                id={id}
                                onClick={e => {
                                    changeClass(correctId, 'correct')
                                    changeClass(id, 'incorrect')
                                    props.answerQuestion(e, 'incorrect')
                                }}>
                            {answer}</button>)})
                            
        allAnswers.push(correctAnswer)
       
       React.useEffect(function() {
           allAnswers = shuffle(allAnswers)
        }, [])```

Solution

  • I solved the problem by setting state of a randomly sorted array within use effect only changing when props.result changed

    const [randomArray, setRandomArray] = React.useState([])
    
    React.useEffect(function() {
    setRandomArray(shuffle(allAnswers))
    }, [props.result])