簡體   English   中英

如何在反應掛鈎中創建可重用的 state?

[英]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 作為標志

(實際上,我不像下一個那樣喜歡這個;所以請閱讀它,然后繼續閱讀。)

您可以將這些函數放在一個數組中,並可能使標志成為 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。

使用 object 作為按鈕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 鈎子的更多信息。

https://reactjs.org/docs/hooks-reference.html#usereducer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM