React Hooks: Component is not rendering in Nested Routing

Viewed 192

I am using "react-scripts": "4.0.2" and all my components are React Hooks. My logic involves nested routing but the end result is not rendered.

App.js:

<BrowserRouter>
  <div className="App">
    <TopNav />
    <Home />
  </div>
</BrowserRouter>

Home.js:

<Switch>
    <Route path="/" component={Questions} />
</Switch>

Questions.js

    const displayQuestion = (qid) => {
         props.history.push({ pathname: "/question/" + qid });
      };
    
//questions is an array of objects

      const questionsBlocks = questions.map((quest, i) => {
        return (
          <QBlock
            key={i + 1}
            qno={i + 1}
            displayQuestion={displayQuestion.bind(this, quest.qid)}
          />
        );
      });
    
      return (
        <div>
          <h1>Questions</h1>
          {questionsBlocks}
          <Switch>
            <Route
              path="/question/:id"
              render={(props) => <Question {...props} questions={questions} />}
            />
          </Switch>
        </div>
      );

QBlock will only render buttons that will call displayQuestion on being clicked

QBlock.js:

  return (
    <div className="block" onClick={props.displayQuestion}>
      <h1>{props.qno}</h1>
    </div>
  );

Question.js:

const [question, setQuestion] = useState();

  const loadQuestion = () => {
    console.log(props);
    if (props.match.params.id) {
      console.log("load called");
      const qid = props.match.params.id;
      const index = props.questions.findIndex((quest) => quest.qid == qid);
      setQuestion(props.questions[index]);
    }
  };

  // componentDidMount with react hooks
  useEffect(() => {
    console.log("Mounted");
    loadQuestion();
  }, []);

  // componentDidUpdate with react hooks
  useEffect(() => {
    console.log("Updated");
    loadQuestion();
  }, [props.match.params.id]); //Even tried with only props

  return (
    <div className="Quest">
      <div className="question">{question.question}</div>
      <div className="options">{question.answerChoices}</div>
    </div>
  );

Neither of the useEffect of Question.js is not executing still I am getting the following error.

enter image description here

2 Answers

Basically, question needs to be initialized

const [question, setQuestion] = useState(null);

And another thing you need to do is to check the value of question before using it

return (
    <div className="Quest">
      {question && question.question && <div className="question">{question.question}</div>}
      {question && question.answerChoices && <div className="options">{question.answerChoices}</div>}
    </div>
  );

As Vince said.. I had defined useState like const [question, setQuestion] = useState(); instead of const [question, setQuestion] = useState({});

Related