[英]how to create reusable state in react hooks?
我的應用程序中有 5 個按鈕,我想根據按鈕狀態更改背景顏色,所以現在當我單擊一個按鈕時,它會影響所有按鈕,這些按鈕用於在 UI 中復制某些內容,每個按鈕復制不同的內容。
注意:我知道我可以為每個按鈕創建五個狀態,一切都會好起來的,但我認為這是一個糟糕的解決方案。
此外,假設每個都有自己的圖標和文本,我們應該能夠COPIED
按鈕將文本更改為已復制並更改按鈕的圖標
像這里這樣。
這是我到目前為止所擁有的
import React, { useState, useEffect, useRef } from 'react';
function Mata() {
const [isCopied, setIsCopied] = useState(0);
return (
<div className="container">
<button style={{ backgroundColor: isCopied ? '#262626' : '#F3F3F3'}} className={`btn1 ${isCopied && activeTab}`} onClick={handleBtn1}>Copy anything</button>
<button style={{ backgroundColor: isCopied ? '#262626' : '#F3F3F3'}} className={`btn2 ${isCopied && activeTab}`} onClick={handleBtn2}>Copy something</button>
<button style={{ backgroundColor: isCopied ? '#262626' : '#F3F3F3'}} className={`btn3 ${isCopied && activeTab}`} onClick={handleBtn3}>Copy Imgae</button>
<button style={{ backgroundColor: isCopied ? '#262626' : '#F3F3F3'}} className={`btn4 ${isCopied && activeTab}`} onClick={handleBtn4}>Copy text</button>
<button style={{ backgroundColor: isCopied ? '#262626' : '#F3F3F3'}} className={`btn5 ${isCopied && activeTab}`} onClick={handleBtn5}>Copy Link</button>
</div>
)
}
export default Mata
我怎樣才能只創建一個 state 例如const[isCopied, setIsCopied] = useState()
; 並在與在 UI 中復制某些內容相關的任何按鈕中使用它?
也許創建你自己的 React 組件來封裝你的想法,並使用該組件。
這是一個 代碼框,展示了如何對其進行自定義以滿足您的需求,以及為每個按鈕的 onClick 事件傳遞 function。
下面是一個簡單的片段。
import React, { useState } from "react";
import "./styles.css";
export default function App() {
return (
<div className="App">
<ColouredButton title="Copy something" />
<ColouredButton title="Copy something" />
<ColouredButton title="Copy Imgae" />
<ColouredButton title="Copy text" />
<ColouredButton title="Copy Link" />
</div>
);
}
const ColouredButton = props => {
const [isCopied, setIsCopied] = useState(0);
return (
<button
style={{ backgroundColor: isCopied ? "#262626" : "#F3F3F3" }}
className={`btn1 ${isCopied && activeTab}`}
onClick={() => setIsCopied(prevState => !prevState)}
>
{props.title}
</button>
);
};
這里可能有三個不同的答案:
useState
調用由於您已經說過處理程序都是獨立的,並且您正在單獨編寫按鈕,所以我只使用五個useState
調用。 簡單、清晰,避免按鈕之間的串擾。
但是你說過你不想那樣做,所以繼續回答#2 ... :-)
(實際上,我不像下一個那樣喜歡這個;所以請閱讀它,然后繼續閱讀。)
您可以將這些函數放在一個數組中,並可能使標志成為 object 鍵控按鈕的id
,我們可以從索引創建它:
function Mata() {
const [isCopied, setIsCopied] = useState({});
// ...create handlers...
const buttonHandlers = [handleBtn1, handleBtn2, handleBtn3, handleBtn4, handleBtn5];
return (
<div className="container">
{buttonHandlers.map((handleBtn, index) => {
const flag = isCopied[index];
return <button id={index} style={{ backgroundColor: flag ? '#262626' : '#F3F3F3'}} className={`btn${index+1} ${flag && activeTab}`} onClick={handleBtn}>Copy anything</button>;
})}
</div>
);
}
在處理程序 function 中:
function handleBtn1(evt) {
// ...logic...
if (/*...need to set the flag...*/) {
setIsCopied(isCopied => ({...isCopied, [evt.target.id]: true}));
} else if (/*...need to clear the flag...*/) {
setIsCopied(isCopied => ({...isCopied, [evt.target.id]: true}));
}
}
有人可能會告訴你, id
值不能以數字開頭。 這是不正確的,他們可以。 它是 CSS ID 選擇器,不能以未轉義的數字開頭,但我們在這里沒有使用 CSS。
id
鍵控的標志或者完全取消數組,因為它不再給你買太多東西了:
function Mata() {
const [isCopied, setIsCopied] = useState({});
// ...create handlers...
return (
<div className="container">
<button id="btn1" style={{ backgroundColor: isCopied.btn1 ? '#262626' : '#F3F3F3'}} className={`btn1 ${isCopied.btn1 && activeTab}`} onClick={handleBtn1}>Copy anything</button>
<button id="btn2" style={{ backgroundColor: isCopied.btn2 ? '#262626' : '#F3F3F3'}} className={`btn2 ${isCopied.btn2 && activeTab}`} onClick={handleBtn2}>Copy something</button>
<button id="btn3" style={{ backgroundColor: isCopied.btn3 ? '#262626' : '#F3F3F3'}} className={`btn3 ${isCopied.btn3 && activeTab}`} onClick={handleBtn3}>Copy Imgae</button>
<button id="btn4" style={{ backgroundColor: isCopied.btn4 ? '#262626' : '#F3F3F3'}} className={`btn4 ${isCopied.btn4 && activeTab}`} onClick={handleBtn4}>Copy text</button>
<button id="btn5" style={{ backgroundColor: isCopied.btn5 ? '#262626' : '#F3F3F3'}} className={`btn5 ${isCopied.btn5 && activeTab}`} onClick={handleBtn5}>Copy Link</button>
</div>
);
}
您可能想為此嘗試useReducer()
鈎子。
如果您之前有使用過 redux 的經驗,您可以輕松理解這個概念。
您可以在此處閱讀有關 useReducer 鈎子的更多信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.