重复键警告和 ui 行为异常
Duplicates keys warning and ui acts strange
作为快速学习的一部分,我正在尝试实现井字游戏,但遇到了 2 个奇怪的问题。我试图查看 CSS,它使用 Flexbox 并固定高度和宽度,我填满整行它又回到原来的形状。
尽管我给了它唯一的键,但我得到了重复的警告键。
当点击元素时,方块掉落!好奇怪。
谢谢,
import React, { useState } from 'react';
import './App.css';
const checkWinner = ({ board }) => {
}
const setXo = ({ board, setBoard, row, col, nextPlayer, setNextPlayer }) => {
if (board[row][col] !== null)
return alert('already in use')
if (nextPlayer) {
const newBoard = board
newBoard[row][col] = 'O'
setBoard(newBoard)
} else {
const newBoard = board
newBoard[row][col] = 'X'
setBoard(newBoard)
}
setNextPlayer(!nextPlayer)
}
const Row = props => {
return (
<button style={{ width: 100, height: 100 }} onClick={() => setXo(props)}>
<h1>{props.board[props.row][props.col]}</h1>
</button>
)
}
const Column = props => props.board.map((value, index) => {
console.log([props.row,index].join(''))
return (
<Row
board={props.board}
setBoard={props.setBoard}
row={props.row}
col={index}
key={[props.row,index].join('')}
nextPlayer={props.nextPlayer}
setNextPlayer={props.setNextPlayer}
/>
)
})
const Board = props => {
console.log(props.board.length)
return props.board.map((i, index) => {
console.log(`index is: ${index}`)
return (
<div style={{ height: 100 }}>
<Column
key={index.toString()}
row={index}
style={{ marginTop: 20, border: 2, borderColor: 'black' }}
board={props.board}
setBoard={props.setBoard}
nextPlayer={props.nextPlayer}
setNextPlayer={props.setNextPlayer}
/>
</div>)
})
}
const App = () => {
const INITIAL_BOARD = Array(3).fill(null).map(() => Array(3).fill(null));
const [nextPlayer, setNextPlayer] = useState(false)
const [board, setBoard] = useState(INITIAL_BOARD)
const setPlayer = nextPlayer => nextPlayer ? 'Player 2' : 'Player 1'
console.log(board)
return (
<div className="App">
<h2>X/O Game</h2>
<Board
board={board}
setBoard={setBoard}
nextPlayer={nextPlayer}
setNextPlayer={setNextPlayer}
/>
<h2>The next player is: {setPlayer(nextPlayer)}</h2>
</div>
);
}
export default App;
这是 UI 问题:
关键部分我来回答一下
您现在的密码是:
const Board = props => {
console.log(props.board.length)
return props.board.map((i, index) => {
console.log(`index is: ${index}`)
return (
<div style={{ height: 100 }}>
<Column
key={index.toString()}
row={index}
style={{ marginTop: 20, border: 2, borderColor: 'black' }}
board={props.board}
setBoard={props.setBoard}
nextPlayer={props.nextPlayer}
setNextPlayer={props.setNextPlayer}
/>
</div>)
})
}
如您所见,您正在为 Column 组件提供密钥。这是不正确的。正确的做法是给包装列的 div
标签一个键。
这样做的原因是密钥用于防止不必要的重新渲染。如果你把它放在 Column
中,你的 divs
仍然会被重新渲染,这不是你想要发生的。所以永远记住——当映射和返回一堆元素时,总是把 key
放在要返回的最上面的元素上。
作为快速学习的一部分,我正在尝试实现井字游戏,但遇到了 2 个奇怪的问题。我试图查看 CSS,它使用 Flexbox 并固定高度和宽度,我填满整行它又回到原来的形状。
尽管我给了它唯一的键,但我得到了重复的警告键。
当点击元素时,方块掉落!好奇怪。
谢谢,
import React, { useState } from 'react';
import './App.css';
const checkWinner = ({ board }) => {
}
const setXo = ({ board, setBoard, row, col, nextPlayer, setNextPlayer }) => {
if (board[row][col] !== null)
return alert('already in use')
if (nextPlayer) {
const newBoard = board
newBoard[row][col] = 'O'
setBoard(newBoard)
} else {
const newBoard = board
newBoard[row][col] = 'X'
setBoard(newBoard)
}
setNextPlayer(!nextPlayer)
}
const Row = props => {
return (
<button style={{ width: 100, height: 100 }} onClick={() => setXo(props)}>
<h1>{props.board[props.row][props.col]}</h1>
</button>
)
}
const Column = props => props.board.map((value, index) => {
console.log([props.row,index].join(''))
return (
<Row
board={props.board}
setBoard={props.setBoard}
row={props.row}
col={index}
key={[props.row,index].join('')}
nextPlayer={props.nextPlayer}
setNextPlayer={props.setNextPlayer}
/>
)
})
const Board = props => {
console.log(props.board.length)
return props.board.map((i, index) => {
console.log(`index is: ${index}`)
return (
<div style={{ height: 100 }}>
<Column
key={index.toString()}
row={index}
style={{ marginTop: 20, border: 2, borderColor: 'black' }}
board={props.board}
setBoard={props.setBoard}
nextPlayer={props.nextPlayer}
setNextPlayer={props.setNextPlayer}
/>
</div>)
})
}
const App = () => {
const INITIAL_BOARD = Array(3).fill(null).map(() => Array(3).fill(null));
const [nextPlayer, setNextPlayer] = useState(false)
const [board, setBoard] = useState(INITIAL_BOARD)
const setPlayer = nextPlayer => nextPlayer ? 'Player 2' : 'Player 1'
console.log(board)
return (
<div className="App">
<h2>X/O Game</h2>
<Board
board={board}
setBoard={setBoard}
nextPlayer={nextPlayer}
setNextPlayer={setNextPlayer}
/>
<h2>The next player is: {setPlayer(nextPlayer)}</h2>
</div>
);
}
export default App;
这是 UI 问题:
关键部分我来回答一下
您现在的密码是:
const Board = props => {
console.log(props.board.length)
return props.board.map((i, index) => {
console.log(`index is: ${index}`)
return (
<div style={{ height: 100 }}>
<Column
key={index.toString()}
row={index}
style={{ marginTop: 20, border: 2, borderColor: 'black' }}
board={props.board}
setBoard={props.setBoard}
nextPlayer={props.nextPlayer}
setNextPlayer={props.setNextPlayer}
/>
</div>)
})
}
如您所见,您正在为 Column 组件提供密钥。这是不正确的。正确的做法是给包装列的 div
标签一个键。
这样做的原因是密钥用于防止不必要的重新渲染。如果你把它放在 Column
中,你的 divs
仍然会被重新渲染,这不是你想要发生的。所以永远记住——当映射和返回一堆元素时,总是把 key
放在要返回的最上面的元素上。