React数独求解器开发问题:子组件无法实时更新父组件Board状态
Hey there! I see the issue you're facing—your parent Board component isn't updating immediately when you modify the board from the Possibles child component. Let's break down why this happens and how to fix it.
The Root Cause
In your Possibles component's updateGrid function, you're directly mutating the original board state array:
board[pos[0]][pos[1]] = opt; setGrid(board);
React relies on reference changes to detect state updates. When you mutate the original array (instead of creating a new one), the board variable still points to the same memory reference. So when you call setGrid(board), React thinks nothing has changed and skips re-rendering the parent component. The changes only show up later when you toggle the selected state (which triggers a re-render, pulling in the mutated values).
The Fix: Create a New Array Copy
To fix this, you need to create a deep copy of the board array (since it's a 2D array) before modifying it, then pass this new copy to setGrid. Here's how to update your Possibles component:
Updated Possibles Component Code
import React, { useState, useEffect } from 'react'; import { getAvailableNumbers } from '../help'; function Possibles({ board, pos, setGrid }) { const [possibles, setPosibles] = useState([]); useEffect(() => { const avails = getAvailableNumbers(board, pos); avails.unshift(0); setPosibles(avails); // Removed extra unnecessary arguments here }, [pos, board]); const updateGrid = (opt) => { // Create a deep copy of the 2D board array const newBoard = board.map(row => [...row]); // Update the selected cell in the copied array newBoard[pos[0]][pos[1]] = opt; // Pass the new array to setGrid to trigger a state update setGrid(newBoard); }; return ( <div> {possibles.map((opt) => ( <button type="button" key={opt} onClick={() => updateGrid(opt)} >{opt === 0 ? 'X' : opt}</button> ))} </div> ); } export default Possibles;
Bonus: Fix a Small Bug in the Parent Component
I also noticed a tiny mistake in your Board component's render logic for Possibles:
{setSolved ? <Possibles board={grid} pos={selected} setGrid={setGrid} setPos = {setSelected}/> : ''}
You're checking setSolved (the state updater function) instead of solved (the actual state value). Change this to:
{solved ? <Possibles board={grid} pos={selected} setGrid={setGrid} setPos={setSelected} /> : ''}
Why This Works
By creating a new array copy with board.map(row => [...row]), you're giving React a new reference to detect as a state change. When you call setGrid(newBoard), React recognizes the new reference and triggers a re-render of the parent component, showing your changes immediately.
内容的提问来源于stack exchange,提问作者Bimarsha Khanal

