[英]Map array to return components with different classNames
我正在嘗試做一個應用程序,該應用程序創建一個帶有7 段 LED 顯示屏的組件,但 LED 顯示屏應顯示輸入的數字。 我一直試圖用邏輯來思考這個問題,但它不起作用。
switch
,並且根據輸入的數字,它會將包含禁用樣式的className
添加到每個div
。當我嘗試只輸入一個數字時,它工作正常! 但是當我用兩個數字嘗試它時,它只是錯誤。 正如您在圖片中看到的:
我只有兩個組件: <App/>
和<Numbers/>
。
應用程序:
function App() {
const [input, setInput] = useState('');
const [number, setNumber] = useState([]);
const changeNumbers = () => {
// Splitting inputted numbers to add each number to array.
const inputSplit = input.toString().split('');
const inputArray = inputSplit.map(Number);
setNumber(inputArray);
}
return (
<div>
<input onChange={(e) => {setInput(e.target.value)}}/>
<button onClick={() => {changeNumbers()}}>Confirm</button>
{
number.length ?
number.map((singleNumber, idx) => (
<Numbers singleNumber={singleNumber} key={idx} />
))
:
<Numbers singleNumber={0} />
}
</div>
);
}
數字:
const Numbers = ({ singleNumber }) => {
const switchDisabled = (element) => {
const segmentB = document.querySelector('.segment-b');
const segmentC = document.querySelector('.segment-c');
const segmentF = document.querySelector('.segment-f');
switch(element) {
case 2:
segmentC.classList.add('segment-disabled');
segmentF.classList.add('segment-disabled');
break;
case 6:
segmentB.classList.add('segment-disabled');
break;
default:
break;
}
}
useEffect(() => {
switchDisabled(singleNumber);
}, [singleNumber]);
return (
<div className="container">
<div className="segment segment-a"></div>
<div className="segment segment-b"></div>
<div className="segment segment-c"></div>
<div className="segment segment-d"></div>
<div className="segment segment-e"></div>
<div className="segment segment-f"></div>
<div className="segment segment-g"></div>
</div>
)
}
款式:
.container {
width: 110px;
height: 160px;
position: relative; }
.segment {
position: absolute;
background-color: red; }
.segment-a {
top: 0;
left: 10px;
width: 90px;
height: 10px; }
.segment-b {
top: 13px;
right: 0;
height: 60px;
width: 10px; }
.segment-c {
bottom: 13px;
right: 0;
height: 60px;
width: 10px; }
.segment-d {
bottom: 0;
left: 10px;
width: 90px;
height: 10px; }
.segment-e {
bottom: 13px;
left: 0;
height: 60px;
width: 10px; }
.segment-f {
top: 13px;
left: 0;
height: 60px;
width: 10px; }
.segment-g {
top: 75px;
left: 16px;
width: 80px;
height: 10px; }
.segment-disabled {opacity: 0.1;}
Obs:我沒有張貼imports
和exports
以節省空間。
問題是在Numbers
組件中調用document.querySelector
來獲取一個段,例如
const segmentB = document.querySelector('.segment-b');
此調用將在整個頁面上找到第一個 DOM 元素,該元素的類包含segment-b
,這意味着錯誤的數字在呈現第二個數字時更改了它的段。 您可以通過輸入一個兩位數相同的數字來驗證這一點,例如 66 - 第一個數字應呈現為6
,而第二個數字將不正確。
您可以不使用帶有classList.add
和classList.remove
document.querySelector
,而是使用動態變量來計算每個 Number 組件中所需的禁用段類,然后在該特定 Number 組件上呈現這些類:
const Numbers = ({ singleNumber }) => {
const switchDisabled = (element) => {
const allSegments = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
let disabledSegments = [];
switch (element) {
case 2:
disabledSegments.push("c");
disabledSegments.push("f");
break;
case 6:
disabledSegments.push("b");
break;
default:
break;
}
};
return (
<div className="container">
{allSegments.forEach(segmentLetter => {
const disabledClass = disabledSegments.includes(segmentLetter) ? 'segment-disabled' : '';
return (
<div className={`segment segment-${segmentLetter} ${disabledClass}`} />
)
})}
</div>
);
};
PS 一般來說,由於這些類型的問題,您希望在 99.99% 的時間內調用document.querySelector
反應方式是不通過調用 dom 節點而是構建 dom 節點來操縱 dom。 因此,不要通過調用 dom 節點來添加類,只需使用已經到位的類來構建 dom 節點。
在您的應用程序組件中,您可以將輸入設置為字符串,然后將其拆分並循環遍歷它,為每個組件放置一個數字組件。 在您的數字組件中,您只需在數組中設置所需的段,並通過它們映射放置組件呈現時所需的類名。
這是一個codesandbox示例led顯示codeandbox
應用程序.js
import { useState } from "react";
import Number from "./Number";
function App() {
const [input, setInput] = useState("0");
return (
<>
<input
onChange={(e) => {
setInput(e.target.value);
}}
/>
{input.split("").map((number, i) => (
<Number key={i} number={number} />
))}
</>
);
}
export default App;
數字.js
const Number = ({ number }) => {
let segments = [];
switch (number) {
case "1":
segments = ["b", "c"];
break;
case "2":
segments = ["a", "b", "d", "e", "g"];
break;
case "3":
segments = ["a", "b", "c", "d", "g"];
break;
case "4":
segments = ["b", "c", "f", "g"];
break;
case "5":
segments = ["a", "c", "d", "f", "g"];
break;
case "6":
segments = ["a", "c", "d", "f", "e", "g"];
break;
case "7":
segments = ["a", "b", "c"];
break;
case "8":
segments = ["a", "b", "c", "d", "e", "f", "g"];
break;
case "9":
segments = ["a", "b", "c", "d", "f", "g"];
break;
case "0":
segments = ["a", "b", "c", "d", "e", "f"];
break;
default:
segments = ["a", "b", "c", "d", "e", "f"];
}
return (
<div className="container">
{segments.map((segment) => (
<div key={segment} className={`segment segment-${segment}`}></div>
))}
</div>
);
};
export default Number;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.