父组件不会从子组件更改

Parent component doesn't change from child component

我正在尝试制作数独解算器。我有一个父组件 Board 和一个子组件 Possible,它们显示面板中任何框的可用选项。我通过了棋盘状态,selected(棋盘中选定的框位置)并具有更新棋盘作为道具的功能。但是,当我尝试从 Possible 更改 board 时,除非所选框 selected 从父组件更改,否则它不会更改。我正在尝试从子组件更改 board 元素。

这是我的 Board 组件。

import React, { useState } from 'react';
import Possibles from './avails.jsx';
import solve, { initBoard } from '../help';

function Board() {
  const [msg, setmsg] = useState('');
  const [solved, setSolved] = useState(false);
  const [grid, setGrid] = useState(initBoard());

  const [selected, setSelected] = useState([0, 0]);

  const solveBoard = () => {
    const solution = solve(grid);
    setGrid(solution);
    setSolved(true);
    let a = true;
    for (let i = 0; i < 9; i++) {
      for (let j = 0; j < 9; j++) {
        // console.log(i,j)
        if (grid[i][j] === 0) {
        //   console.log(grid[i][j]);
          a = false;
        }
      }
    }
    if (!a) {
      setmsg('Invalid Board!');
    } else setmsg('Here is your solution!');
  };
  const updatePosition = (row, col) => {
    setSelected([row, col]);
  };
  const resetBoard = () => {
    setGrid(initBoard());
    setSolved(!solved);
    setmsg('');
  };
  return (
    <div className="board">
      Sudoku Solver
      {grid.map((row, index) => (
        <div key={index} className="row">
          {row.map((el, i) => (
            <button
              type="button"
              key={i}
              className={selected[0] === index && selected[1] === i ? 'el selected' : 'el'}
              onClick={() => { updatePosition(index, i); }}
            >
              {el === 0 ? '' : el}
            </button>

          ))}
        </div>
      ))}
      {setSolved
        ? <Possibles board={grid} pos={selected} setGrid={setGrid} setPos = {setSelected}/> : ''}
      <button type="button" className="btn" onClick={solveBoard}>Solve</button>
      <button type="button" className="btn" onClick={resetBoard}>Reset</button>
      <div>{msg}</div>
    </div>
  );
}

export default Board;

这是我的子组件 Possibles

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, board, possibles);
  }, [pos,board]);

  const updateGrid = (opt) => {
    // setPosibles((prev) => prev.filter((x) => x !== opt || x === 0));
    board[pos[0]][pos[1]] = opt;
    setGrid(board);
  };
  return (
    <div>
      {possibles.map((opt) => (
        <button type="button" key={opt} onClick={() => { updateGrid(opt); }}>{opt === 0 ? 'X' : opt}</button>
      ))}

    </div>
  );
}

export default Possibles;

请将您的 'updateGrid' 函数更改为 -

const updateGrid = (opt) => {
    // setPosibles((prev) => prev.filter((x) => x !== opt || x === 0));
    board[pos[0]][pos[1]] = opt;
    board = [...board]; // this will make parent component rerender 
    setGrid(board);
  };

根据 'Possibles' 组件的第一行,setPosibles 的输入应该是一个数组 -

setPosibles(avails, board, possibles);

编辑 - React 基本上使用 props, state 的浅层比较来检测新的可用更改。通过使用 spread operator 我们正在创建具有新内存位置的新数组,这让 React 知道新的变化并触发重新渲染。