So I'm building a quiz app and that quiz is divided into difficulty levels. I change that level on a button click by setting params into my path. Then I try to insert a difficulty index because the structure of my obj is:
const questions = {
easy: [...],
medium: [...],
hard: [...]
}
const [searchParams, setSearchParams] = useSearchParams();
const [currentPage, setCurrentPage] = useState(0);
const difficulty = searchParams.get("difficulty");
const handlePageChange = () => {
if (currentPage 1 < questions[difficulty].length) {
setCurrentPage((prevState) => prevState 1);
}
};
const handleDifficultyChoice = (difficulty: DifficultyType) => {
setSearchParams({ difficulty });
};
Unfortunately I cannot insert that index because index cannot be null. How to solve that?
CodePudding user response:
You can replace the contents of the handlePageChange
function with the following code, which will guarantee that difficulty
is a valid property key in questions
before executing the code after the conditional expression:
if (
// This expresion evaluates to true or false,
// depending on whether difficulty is a valid property key in questions:
(difficulty as DifficultyType) in questions
// If it evaluates to false, this one won't execute:
&& currentPage 1 < questions[difficulty as DifficultyType].length
// and neither will the setCurrentPage invocation:
) setCurrentPage((prevState) => prevState 1);
Reference: The
difficulty as DifficultyType
syntax is what's called a type assertion.
Here's a full, reproducible example in the TypeScript Playground:
import {useState} from 'react';
import {useSearchParams} from 'react-router-dom';
const questions = {
easy: [],
medium: [],
hard: []
};
type DifficultyType = keyof typeof questions;
function Component () {
const [searchParams, setSearchParams] = useSearchParams();
const [currentPage, setCurrentPage] = useState(0);
const difficulty = searchParams.get("difficulty");
const handlePageChange = () => {
if (
(difficulty as DifficultyType) in questions
&& currentPage 1 < questions[difficulty as DifficultyType].length
) setCurrentPage((prevState) => prevState 1);
};
const handleDifficultyChoice = (difficulty: DifficultyType) => {
setSearchParams({ difficulty });
};
}
See also: type guard functions in the TS handbook
CodePudding user response:
URLSearchParams.get returns a string value or null.
Check if difficulty
is truthy prior to using it as a dynamic key.
Example:
const handlePageChange = () => {
if (difficulty && currentPage 1 < questions[difficulty]?.length) {
setCurrentPage((prevState) => prevState 1);
}
};