父组件不会从子组件更改
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 知道新的变化并触发重新渲染。
我正在尝试制作数独解算器。我有一个父组件 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 知道新的变化并触发重新渲染。