I have a Sudoku solver project in react. And I want to style it with react or css. I tried both ways and ended up in a confusion. The grid component is my main component and I want to style the board like this:
And here is my simple CSS code
JavaScript
x
4
1
.odd {
2
background-color: gray;
3
}
4
And my Grid.jsx
JavaScript
1
140
140
1
import React, { useEffect } from 'react'
2
import '../App.css';
3
4
5
export default function Grid() {
6
// for every input make sure only one number per an input field can be entered
7
const checkInput = (e) => {
8
if (e.target.value.length > 1) {
9
e.target.value = e.target.value.slice(0, 1)
10
}
11
}
12
13
// Driver function for the grid
14
const grid = document.querySelectorAll('.grid input')
15
16
useEffect(() => {
17
grid.forEach(item => {
18
item.addEventListener('input', checkInput)
19
})
20
21
return () => {
22
grid.forEach(item => {
23
item.removeEventListener('input', checkInput)
24
})
25
}
26
}, [grid])
27
28
// styling for grid element
29
30
31
useEffect(() => {
32
const colorChanger = () => {
33
grid.forEach((item, i) => {
34
if (
35
((i % 9 === 0 || i % 9 === 1 || i % 9 === 2) && i < 21) ||
36
((i % 9 === 6 || i % 9 === 7 || i % 9 === 8) && i < 27) ||
37
((i % 9 === 3 || i % 9 === 4 || i % 9 === 5) && (i > 27 && i < 53)) ||
38
((i % 9 === 0 || i % 9 === 1 || i % 9 === 2) && i > 53) ||
39
((i % 9 === 6 || i % 9 === 7 || i % 9 === 8) && i > 53)
40
) {
41
item.classList.add('odd')
42
}
43
})
44
}
45
colorChanger()
46
}, [grid])
47
48
return (
49
<div className='grid'>
50
<input type="number" min='1' max='9' />
51
<input type="number" min='1' max='9' />
52
<input type="number" min='1' max='9' />
53
<input type="number" min='1' max='9' />
54
<input type="number" min='1' max='9' />
55
<input type="number" min='1' max='9' />
56
<input type="number" min='1' max='9' />
57
<input type="number" min='1' max='9' />
58
<input type="number" min='1' max='9' />
59
<input type="number" min='1' max='9' />
60
<input type="number" min='1' max='9' />
61
<input type="number" min='1' max='9' />
62
<input type="number" min='1' max='9' />
63
<input type="number" min='1' max='9' />
64
<input type="number" min='1' max='9' />
65
<input type="number" min='1' max='9' />
66
<input type="number" min='1' max='9' />
67
<input type="number" min='1' max='9' />
68
<input type="number" min='1' max='9' />
69
<input type="number" min='1' max='9' />
70
<input type="number" min='1' max='9' />
71
<input type="number" min='1' max='9' />
72
<input type="number" min='1' max='9' />
73
<input type="number" min='1' max='9' />
74
<input type="number" min='1' max='9' />
75
<input type="number" min='1' max='9' />
76
<input type="number" min='1' max='9' />
77
<input type="number" min='1' max='9' />
78
<input type="number" min='1' max='9' />
79
<input type="number" min='1' max='9' />
80
<input type="number" min='1' max='9' />
81
<input type="number" min='1' max='9' />
82
<input type="number" min='1' max='9' />
83
<input type="number" min='1' max='9' />
84
<input type="number" min='1' max='9' />
85
<input type="number" min='1' max='9' />
86
<input type="number" min='1' max='9' />
87
<input type="number" min='1' max='9' />
88
<input type="number" min='1' max='9' />
89
<input type="number" min='1' max='9' />
90
<input type="number" min='1' max='9' />
91
<input type="number" min='1' max='9' />
92
<input type="number" min='1' max='9' />
93
<input type="number" min='1' max='9' />
94
<input type="number" min='1' max='9' />
95
<input type="number" min='1' max='9' />
96
<input type="number" min='1' max='9' />
97
<input type="number" min='1' max='9' />
98
<input type="number" min='1' max='9' />
99
<input type="number" min='1' max='9' />
100
<input type="number" min='1' max='9' />
101
<input type="number" min='1' max='9' />
102
<input type="number" min='1' max='9' />
103
<input type="number" min='1' max='9' />
104
<input type="number" min='1' max='9' />
105
<input type="number" min='1' max='9' />
106
<input type="number" min='1' max='9' />
107
<input type="number" min='1' max='9' />
108
<input type="number" min='1' max='9' />
109
<input type="number" min='1' max='9' />
110
<input type="number" min='1' max='9' />
111
<input type="number" min='1' max='9' />
112
<input type="number" min='1' max='9' />
113
<input type="number" min='1' max='9' />
114
<input type="number" min='1' max='9' />
115
<input type="number" min='1' max='9' />
116
<input type="number" min='1' max='9' />
117
<input type="number" min='1' max='9' />
118
<input type="number" min='1' max='9' />
119
<input type="number" min='1' max='9' />
120
<input type="number" min='1' max='9' />
121
<input type="number" min='1' max='9' />
122
<input type="number" min='1' max='9' />
123
<input type="number" min='1' max='9' />
124
<input type="number" min='1' max='9' />
125
<input type="number" min='1' max='9' />
126
<input type="number" min='1' max='9' />
127
<input type="number" min='1' max='9' />
128
<input type="number" min='1' max='9' />
129
<input type="number" min='1' max='9' />
130
<input type="number" min='1' max='9' />
131
</div>
132
)
133
}
134
135
136
<!-- language: lang-html -->
137
138
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
139
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
140
So how can I achieve the same result in the picture ?
Advertisement
Answer
I suggest you to use a more standard React approach, which is to use Composition. Basically in your Grid you have cells, which is the smallest Component, then you have 9 Squares, which are subunits of 9 cells.
This is a perfect example of composition:
JavaScript
1
43
43
1
const useEffect = React.useEffect
2
const useState = React.useState
3
4
const cells = Array(9)
5
.fill("")
6
.map((el, i) => i);
7
const squares = [cells]
8
9
const Cell = () => {
10
const [val, setVal] = useState(1);
11
12
const onChange = (e) => setVal(+e.target.value);
13
14
return (
15
<input
16
className="cell"
17
type="number"
18
min="1"
19
max="9"
20
onChange={onChange}
21
value={val}
22
/>
23
);
24
};
25
26
const Square = ({ type }) => (
27
<div className={`square ${type}`}>
28
{cells.map((c) => (
29
<Cell key={c} />
30
))}
31
</div>
32
);
33
34
const Grid = () => (
35
<div className="grid">
36
{squares.map((el, i) => (
37
<Square key={el} type={i % 2 !== 0 ? "light" : "dark"} />
38
))}
39
</div>
40
);
41
42
43
ReactDOM.render(<Grid />, document.getElementById("root"))
JavaScript
1
23
23
1
.grid {
2
width: 396px;
3
height: 396px;
4
}
5
6
.cell {
7
width:40px;
8
height:40px;
9
padding:0;
10
background:none;
11
}
12
13
.square {
14
display:inline-block;
15
width: 132px;
16
height: 132px;
17
margin:0;
18
padding:0;
19
}
20
21
.dark {
22
background: gray;
23
}
JavaScript
1
3
1
<div id="root"></div>
2
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
3
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>