为了账号安全,请及时绑定邮箱和手机立即绑定

React-hooks 在点击时处理多个按钮状态

React-hooks 在点击时处理多个按钮状态

HUH函数 2022-12-18 16:10:31
我的应用程序中有 5 个按钮,我想根据按钮状态更改背景颜色,所以现在当我单击一个按钮时,它会影响所有按钮(切换类),不仅我需要更改按钮颜色,而且我还需要隐藏和显示每个按钮的数据,所以我使用条件渲染,默认选项卡是社交媒体。因此,例如,您单击按钮 1 它会更改背景颜色并显示带有信息的 div 等这是我到目前为止所拥有的    import React, { useState, useEffect, useRef } from 'react';        function Mata() {    const [isBlack, setIsBlack] = useState(0);    const [tab, setTab] = useState('socialmedia');        const handleBtn1 = (e) =>{        e.preventDefault();        setIsBlack(!isBlack);          setTab('data1);     }    const handleBtn2 = (e) =>{        e.preventDefault();        setIsBlack(!isBlack);          setTab('data2');     }    const handleBtn3 = (e) =>{        e.preventDefault();        setIsBlack(!isBlack);         setTab('data3');     }    const handleBtn4 = (e) =>{        e.preventDefault();        setIsBlack(!isBlack);          setTab('data4');     }    const handleBtn5 = (e) =>{        e.preventDefault();        setIsBlack(!isBlack);        setTab('data5');     }我需要更改什么才能使其正常工作?
查看完整描述

2 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

每个按钮都需要单独的状态。我建议使用地图来存储一个按钮 ID 和一个布尔值,以确定它是否为“黑色”,即点击处理程序只是切换一个布尔值。我不知道这是否是将代码复制/粘贴到 SO 时的拼写错误,但需要在功能组件主体中声明反应状态。


const [isBlack, setIsBlack] = useState({});

您还可以通过将其转换为柯里化回调来使用单击处理程序,将按钮 ID 获取并包含在范围内。这使用功能状态更新来浅层复制现有状态并更新包含的按钮 ID 的值。


const handleBtn = btnId => e => {

  e.preventDefault();

  setIsBlack(state => ({

    ...state,

    [btnId]: !state[btnId],

  }));

};

完整代码


function Mata() {

  const [activeTab, setActiveTab] = useState("activeTab");

  const [isBlack, setIsBlack] = useState({});


  const handleBtn = btnId => e => {

    e.preventDefault();

    setIsBlack(state => ({

      ...state,

      [btnId]: !state[btnId]

    }));

  };


  return (

    <div className="container">

      <button

        style={{ backgroundColor: isBlack["btn1"] ? "#262626" : "#F3F3F3" }}

        className={`btn1 ${isBlack["btn1"] && activeTab}`}

        onClick={handleBtn("btn1")}

      >

        btn1

      </button>

      <button

        style={{ backgroundColor: isBlack["btn2"] ? "#262626" : "#F3F3F3" }}

        className={`btn2 ${isBlack["btn2"] && activeTab}`}

        onClick={handleBtn("btn2")}

      >

        btn2

      </button>

      <button

        style={{ backgroundColor: isBlack["btn3"] ? "#262626" : "#F3F3F3" }}

        className={`btn3 ${isBlack["btn3"] && activeTab}`}

        onClick={handleBtn("btn3")}

      >

        btn3

      </button>

      <button

        style={{ backgroundColor: isBlack["btn4"] ? "#262626" : "#F3F3F3" }}

        className={`btn4 ${isBlack["btn4"] && activeTab}`}

        onClick={handleBtn("btn4")}

      >

        btn4

      </button>

      <button

        style={{ backgroundColor: isBlack["btn5"] ? "#262626" : "#F3F3F3" }}

        className={`btn5 ${isBlack["btn5"] && activeTab}`}

        onClick={handleBtn("btn5")}

      >

        btn5

      </button>

    </div>

  );

}

有很多重复的代码,所以一个更干的版本,其中活动选项卡和按钮作为道具传递。


function Mata({ activeTab = '', buttons }) {

  const [isBlack, setIsBlack] = useState({});


  const handleBtn = btnId => e => {

    e.preventDefault();

    setIsBlack(state => ({

      ...state,

      [btnId]: !state[btnId]

    }));

  };


  return (

    <div className="container">

      {buttons.map(btn => (

        <button

          style={{ backgroundColor: isBlack[btn] ? "#262626" : "#F3F3F3" }}

          className={`btn1 ${isBlack[btn] && activeTab}`}

          onClick={handleBtn(btn)}

        >

          {btn}

        </button>

      ))}

    </div>

  );

}

像这样使用


const buttons = ["btn1", "btn2", "btn3", "btn4", "btn5"];


...


<Mata buttons={buttons} />

编辑

似乎你真的在创建一个“标签管理器”。我建议将状态放样到父级并转换Mata为只呈现“选项卡”按钮的“哑”组件。采用 3 个道具:活动选项卡索引、按钮数组和状态更新回调。


function Mata({ activeTab = -1, buttons, setActiveTab }) {

  return (

    <div className="container">

      {buttons.map((btn, i) => {

        const isActive = i === activeTab;

        return (

          <button

            key={btn.id}

            style={{ backgroundColor: isActive ? "#262626" : "#F3F3F3" }}

            className={`${btn.id} ${isActive && activeTab}`}

            onClick={() => setActiveTab(i)}

          >

            {btn.id}

          </button>

        );

      })}

    </div>

  );

}

示例选项卡数据


const tabs = [

  { id: "btn1", data: "data1" },

  { id: "btn2", data: "data2" },

  { id: "btn3", data: "data3" },

  { id: "btn4", data: "data4" },

  { id: "btn5", data: "data5" }

];

用法示例


<Mata activeTab={activeTab} buttons={tabs} setActiveTab={setActiveTab} />


{activeTab === -1 ? (

  <div>Social Media</div>

) : (

  <div>{tabs[activeTab].data}</div>

)}

添加“图标”

类似于在运行时选择类型


如果 SVG 图标还不是反应组件,将它们包装成一个简单的功能组件


const Icon1 = () => <svg>...</svg>;

在标签数据中添加一个图标字段并将值设置为图标组件


const tabs = [

  { id: "btn1", data: "data1", icon: Icon1 },

  { id: "btn2", data: "data2", icon: Icon2 },

  { id: "btn3", data: "data3", icon: Icon3 },

  { id: "btn4", data: "data4", icon: Icon4 },

  { id: "btn5", data: "data5", icon: Icon5 }

];

并解构并重命名以呈现


function Mata({ activeTab = -1, buttons, setActiveTab }) {

  return (

    <div className="container">

      {buttons.map((btn, i) => {

        const isActive = i === activeTab;

        const { icon: Icon, id } = btn; // <-- rename icon -> Icon


        return (

          <button

            key={id}

            style={{ backgroundColor: isActive ? "#262626" : "#F3F3F3" }}

            className={`${id} ${isActive && activeTab}`}

            onClick={() => setActiveTab(i)}

          >

            <Icon /> {id} // <-- render icon component

          </button>

        );

      })}

    </div>

  );

}


查看完整回答
反对 回复 2022-12-18
?
BIG阳

TA贡献1859条经验 获得超6个赞

你为什么做这个


const [isBlack, setIsBlack] = useState(0);

而不是这样做?


const [isBlack, setIsBlack] = useState(false);

另外,要使用 useState,您必须像下面这样编辑代码,因为挂钩只能在函数组件的主体内部调用。


import React, { useState, useEffect, useRef } from "react";


function Mata() {

  const [isBlack, setIsBlack] = useState(false); // correction here


  const handleBtn1 = e => {

    e.preventDefault();

    setIsBlack(!isBlack);

  };

  const handleBtn2 = e => {

    e.preventDefault();

    setIsBlack(!isBlack);

  };

  const handleBtn3 = e => {

    e.preventDefault();

    setIsBlack(!isBlack);

  };

  const handleBtn4 = e => {

    e.preventDefault();

    setIsBlack(!isBlack);

  };

  const handleBtn5 = e => {

    e.preventDefault();

    setIsBlack(!isBlack);

  };

  return (

    <div className="container">

      <button

        style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}

        className={`btn1 ${isBlack && activeTab}`}

        onClick={handleBtn1}

      >

        btn1

      </button>

      <button

        style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}

        className={`btn2 ${isBlack && activeTab}`}

        onClick={handleBtn2}

      >

        btn2

      </button>

      <button

        style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}

        className={`btn3 ${isBlack && activeTab}`}

        onClick={handleBtn3}

      >

        btn3

      </button>

      <button

        style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}

        className={`btn4 ${isBlack && activeTab}`}

        onClick={handleBtn4}

      >

        btn4

      </button>

      <button

        style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}

        className={`btn5 ${isBlack && activeTab}`}

        onClick={handleBtn5}

      >

        btn5

      </button>

    </div>

  );

}


export default Mata;



查看完整回答
反对 回复 2022-12-18
  • 2 回答
  • 0 关注
  • 147 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信