0

I am using a React Context to manage my States, but I am super new to the whole React universe. I have a Next.js App. My Context file:

import { useState, createContext, useContext } from "react";

export const QuizContext = createContext();

export default function QuizProvider({ children }) {
  const [data, setData] = useState({});
  const [isSelected, setisSelected] = useState();

  const setQuizValues = (values) => {
    setData((prevValues) => ({
      ...prevValues,
      ...values,
    }));
  };

  return (
    <QuizContext.Provider value={{ data, isSelected, setisSelected, setQuizValues }}>
      {children}
    </QuizContext.Provider>
  );
}

export const useQuizData = () => useContext(QuizContext);

You see, I also use Context to manage a multistep form, but please ignore this in the code for now. What is not working, is passing setisSelected to my Card component. In the file, where I render several Cards I try to select a Card, using Context. This is just part of my code. All works, except for setisSelected.

export const TacoCathegories = ({quizStep, prevQuizStep, nextQuizStep}) => {
  const { setQuizValues } = useQuizData();
  const quizData = useContext(QuizContext);
  const selectedCard = quizData.isSelected;


  const handleSubmit = (values) => {
    setQuizValues(values);
    prevQuizStep();
    nextQuizStep();
  };

  return (
    <div className={quizStep === 0 ? 'block': 'hidden'}>
      <div className="text-center">
        <h2 className="text-3xl font-extrabold tracking-tight text-gray-600 sm:text-4xl">What is your favourite taco group?</h2>
      </div>
      <div className="max-w-7xl mx-auto py-24 px-4 sm:px-6 lg:px-8">
        <div className="mt space-y-12 lg:space-y-0 lg:grid lg:grid-cols-3 lg:gap-x-8">
          {tacos.map((taco, index) => (
            <Card 
            role="button"
            key={index}
            title={taco.cathegory}
            source={taco.imgURL}
            text={`image of ${taco.cathegory} `}
            selected={selectedCard === index}
            onChange={() => setisSelected(index)}
            />
            
          ))}
        </div>
        {tacos[selectedCard] && <p>{tacos[selectedCard].cathegory}</p>}
        
        <div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-center">
          <div className="rounded-md shadow">
            <a role="button" tabIndex={0}
              className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-gray-200 hover:bg-gray-200 focus:outline-none md:py-4 md:text-lg md:px-10 cursor-not-allowed"
            >
              Back
            </a>
          </div>
          <div className="mt-3 sm:mt-0 sm:ml-3">
            <a
              onClick={nextQuizStep}
              className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-yellow-500 hover:bg-yallow-600 md:py-4 md:text-lg md:px-10"
            >
              Next
            </a>
          </div>
        </div>
      </div>
    </div>
  );
}

I get an Error ReferenceError: setisSelected is not defined. If I do this without the Context, directly in the component, it works. So I assume, I am somehow not passing setisSelected right.

2
  • You just showed the Context definition, it depends on how and where you render it, in next js context usually done in _app file I believe, either way you need to make a full reproducible example, see How to create a Minimal, Reproducible Example Commented Aug 9, 2021 at 8:56
  • Context is included in _app.js, that is right and therefore works for all components. As I mentions, form steps work fine and they are also described in the context. Commented Aug 9, 2021 at 8:57

1 Answer 1

1

You have not extracted the setisSelected from the Context so it's undefined.

 const quizData = useContext(QuizContext);
 const selectedCard = quizData.isSelected;
 const setisSelected = quizData.setisSelected ; // add this

Also you can leverage Object Destructuring to get all the properties in one line from the context

const { selectedCard, setisSelected  } = useContext(QuizContext);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.