I have a state named questions
In a React component.
const [questions, setQuestions] = useState([]);
and a useEffect
method that runs only when the component is rendered the first time.
useEffect(() => {
let questionsArray = [];
//some work is done here to populate the questionsArray
setQuestions(questionsArray);
},[]);
I have a useCallback
method that is created when the component is rendered for the first time.
const updateQuestion = useCallback(() =>{
let new_questions = [...questions];
//do some work here
},[]);
The problem is that questions state inside the updateQuestion
callback is empty because when the component is rendered the first time, the questions state is empty, and the updateQuestion
callback uses the stale questions state for some reason. However, the useEffect
populates the questions state array, and the questions state inside updateQuestion
callback is not up-to-date. I solved this problem by adding questions.length
to the dependencies array of useCallback
like the following
const updateQuestion = useCallback((index) =>{
let new_questions = [...questions];
//do some work here
},[questions.length]);
So, when the questions state is populated with new data in the useEffect
, the updateQuestion
callback is re-created, and the useCallback
will have up-to-date data in questions state. But, are there any other ways that I can get the up-to-date questions state inside the useCallback
without re-creating the callback?
Each item in questions array is used to render a child components named QuestionCard
questions.map((question, index)=>{
return (
<li className="list-group-item border-0" key={question.id}>
<QuestionCard props={question} index={index} updateQuestion={updateQuestion} />
</li>
);
})
The problem is that QuestionCard is a memoized component. If I append an item to the questions state array, the existing items in questions state are the same, they don't need to be rerendered. Now, If i pass questions.array into the dependencies array, the callback is re-created, every child components is rerendered. But, I can't just skip using useCallback and just create a native function. Because, updateQuestion callback is used to update individual question item insides the questions array. If I update a single question, every question will be rerender. If I use useCallback, only the question i am updating is rerendered while i am updating it .