我无法使用 useEffect 在 React 中添加类名,或者?
I can't add a classname in React with useEffect or?
我在 React 中有一个数独求解器项目。我想用 react 或 css 来设计它的样式。我尝试了两种方法,结果陷入了混乱。
网格组件是我的主要组件,我想像这样设置板的样式:
这是我的简单 CSS 代码
.odd {
background-color: gray;
}
还有我的Grid.jsx
import React, { useEffect } from 'react'
import '../App.css';
export default function Grid() {
// for every input make sure only one number per an input field can be entered
const checkInput = (e) => {
if (e.target.value.length > 1) {
e.target.value = e.target.value.slice(0, 1)
}
}
// Driver function for the grid
const grid = document.querySelectorAll('.grid input')
useEffect(() => {
grid.forEach(item => {
item.addEventListener('input', checkInput)
})
return () => {
grid.forEach(item => {
item.removeEventListener('input', checkInput)
})
}
}, [grid])
// styling for grid element
useEffect(() => {
const colorChanger = () => {
grid.forEach((item, i) => {
if (
((i % 9 === 0 || i % 9 === 1 || i % 9 === 2) && i < 21) ||
((i % 9 === 6 || i % 9 === 7 || i % 9 === 8) && i < 27) ||
((i % 9 === 3 || i % 9 === 4 || i % 9 === 5) && (i > 27 && i < 53)) ||
((i % 9 === 0 || i % 9 === 1 || i % 9 === 2) && i > 53) ||
((i % 9 === 6 || i % 9 === 7 || i % 9 === 8) && i > 53)
) {
item.classList.add('odd')
}
})
}
colorChanger()
}, [grid])
return (
<div className='grid'>
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
</div>
)
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
那我怎样才能在图片中达到相同的效果呢?
我的第一个疑问是,如果原则上它是非常静态的,你为什么要动态地进行。
import React, { useEffect } from "react"
import "../App.css"
export default function Grid() {
// for every input make sure only one number per an input field can be entered
const checkInput = (e) => {
if (e.target.value.length > 1) {
e.target.value = e.target.value.slice(0, 1)
}
}
// Driver function for the grid
const grid = document.querySelectorAll(".grid input")
useEffect(() => {
grid.forEach((item) => {
item.addEventListener("input", checkInput)
})
return () => {
grid.forEach((item) => {
item.removeEventListener("input", checkInput)
})
}
}, [grid])
// styling for grid element
const sudoku = [
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
]
var inputs = []
const iterate = [0, 1, 2, 3, 4, 5, 6, 7, 8]
iterate.forEach((i) =>
iterate.forEach((j) =>
inputs.append(
<input
type="number"
className={sudoku[i][j] === 1 ? "odd" : ""}
min="1"
max="9"
/>
)
)
)
return <div className="grid">{inputs}</div>
}
现在是这样
const inputs = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8].forEach((i) => {
[0, 1, 2, 3, 4, 5, 6, 7, 8].forEach((j) => {
inputs.push(
<input
key={`${i}${j}`}
type="number"
className={sudoku[i][j] === 1 ? "odd" : ""}
min="1"
max="9"
/>
)
})
})
return <div className="grid">{inputs}</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
当我插入它时,会附加类名,但我看不到 background-color 的变化
我建议你使用更标准的 React 方法,即使用 Composition。基本上在你的网格中你有 单元格 ,这是最小的组件,然后你有 9 个正方形,它们是 9 个单元格的子单元。
这是一个完美的组合示例:
const useEffect = React.useEffect
const useState = React.useState
const cells = Array(9)
.fill("")
.map((el, i) => i);
const squares = [...cells]
const Cell = () => {
const [val, setVal] = useState(1);
const onChange = (e) => setVal(+e.target.value);
return (
<input
className="cell"
type="number"
min="1"
max="9"
onChange={onChange}
value={val}
/>
);
};
const Square = ({ type }) => (
<div className={`square ${type}`}>
{cells.map((c) => (
<Cell key={c} />
))}
</div>
);
const Grid = () => (
<div className="grid">
{squares.map((el, i) => (
<Square key={el} type={i % 2 !== 0 ? "light" : "dark"} />
))}
</div>
);
ReactDOM.render(<Grid />, document.getElementById("root"))
.grid {
width: 396px;
height: 396px;
}
.cell {
width:40px;
height:40px;
padding:0;
background:none;
}
.square {
display:inline-block;
width: 132px;
height: 132px;
margin:0;
padding:0;
}
.dark {
background: gray;
}
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
我在 React 中有一个数独求解器项目。我想用 react 或 css 来设计它的样式。我尝试了两种方法,结果陷入了混乱。 网格组件是我的主要组件,我想像这样设置板的样式:
这是我的简单 CSS 代码
.odd {
background-color: gray;
}
还有我的Grid.jsx
import React, { useEffect } from 'react'
import '../App.css';
export default function Grid() {
// for every input make sure only one number per an input field can be entered
const checkInput = (e) => {
if (e.target.value.length > 1) {
e.target.value = e.target.value.slice(0, 1)
}
}
// Driver function for the grid
const grid = document.querySelectorAll('.grid input')
useEffect(() => {
grid.forEach(item => {
item.addEventListener('input', checkInput)
})
return () => {
grid.forEach(item => {
item.removeEventListener('input', checkInput)
})
}
}, [grid])
// styling for grid element
useEffect(() => {
const colorChanger = () => {
grid.forEach((item, i) => {
if (
((i % 9 === 0 || i % 9 === 1 || i % 9 === 2) && i < 21) ||
((i % 9 === 6 || i % 9 === 7 || i % 9 === 8) && i < 27) ||
((i % 9 === 3 || i % 9 === 4 || i % 9 === 5) && (i > 27 && i < 53)) ||
((i % 9 === 0 || i % 9 === 1 || i % 9 === 2) && i > 53) ||
((i % 9 === 6 || i % 9 === 7 || i % 9 === 8) && i > 53)
) {
item.classList.add('odd')
}
})
}
colorChanger()
}, [grid])
return (
<div className='grid'>
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
<input type="number" min='1' max='9' />
</div>
)
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
那我怎样才能在图片中达到相同的效果呢?
我的第一个疑问是,如果原则上它是非常静态的,你为什么要动态地进行。
import React, { useEffect } from "react"
import "../App.css"
export default function Grid() {
// for every input make sure only one number per an input field can be entered
const checkInput = (e) => {
if (e.target.value.length > 1) {
e.target.value = e.target.value.slice(0, 1)
}
}
// Driver function for the grid
const grid = document.querySelectorAll(".grid input")
useEffect(() => {
grid.forEach((item) => {
item.addEventListener("input", checkInput)
})
return () => {
grid.forEach((item) => {
item.removeEventListener("input", checkInput)
})
}
}, [grid])
// styling for grid element
const sudoku = [
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1],
]
var inputs = []
const iterate = [0, 1, 2, 3, 4, 5, 6, 7, 8]
iterate.forEach((i) =>
iterate.forEach((j) =>
inputs.append(
<input
type="number"
className={sudoku[i][j] === 1 ? "odd" : ""}
min="1"
max="9"
/>
)
)
)
return <div className="grid">{inputs}</div>
}
现在是这样
const inputs = [];
[0, 1, 2, 3, 4, 5, 6, 7, 8].forEach((i) => {
[0, 1, 2, 3, 4, 5, 6, 7, 8].forEach((j) => {
inputs.push(
<input
key={`${i}${j}`}
type="number"
className={sudoku[i][j] === 1 ? "odd" : ""}
min="1"
max="9"
/>
)
})
})
return <div className="grid">{inputs}</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
当我插入它时,会附加类名,但我看不到 background-color 的变化
我建议你使用更标准的 React 方法,即使用 Composition。基本上在你的网格中你有 单元格 ,这是最小的组件,然后你有 9 个正方形,它们是 9 个单元格的子单元。
这是一个完美的组合示例:
const useEffect = React.useEffect
const useState = React.useState
const cells = Array(9)
.fill("")
.map((el, i) => i);
const squares = [...cells]
const Cell = () => {
const [val, setVal] = useState(1);
const onChange = (e) => setVal(+e.target.value);
return (
<input
className="cell"
type="number"
min="1"
max="9"
onChange={onChange}
value={val}
/>
);
};
const Square = ({ type }) => (
<div className={`square ${type}`}>
{cells.map((c) => (
<Cell key={c} />
))}
</div>
);
const Grid = () => (
<div className="grid">
{squares.map((el, i) => (
<Square key={el} type={i % 2 !== 0 ? "light" : "dark"} />
))}
</div>
);
ReactDOM.render(<Grid />, document.getElementById("root"))
.grid {
width: 396px;
height: 396px;
}
.cell {
width:40px;
height:40px;
padding:0;
background:none;
}
.square {
display:inline-block;
width: 132px;
height: 132px;
margin:0;
padding:0;
}
.dark {
background: gray;
}
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>