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

我的应用程序中有 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'); 

    }


我需要更改什么才能使其正常工作?



HUH函数
浏览 197回答 2
2回答

料青山看我应如是

每个按钮都需要单独的状态。我建议使用地图来存储一个按钮 ID 和一个布尔值,以确定它是否为“黑色”,即点击处理程序只是切换一个布尔值。我不知道这是否是将代码复制/粘贴到 SO 时的拼写错误,但需要在功能组件主体中声明反应状态。const [isBlack, setIsBlack] = useState({});您还可以通过将其转换为柯里化回调来使用单击处理程序,将按钮 ID 获取并包含在范围内。这使用功能状态更新来浅层复制现有状态并更新包含的按钮 ID 的值。const handleBtn = btnId => e => {&nbsp; e.preventDefault();&nbsp; setIsBlack(state => ({&nbsp; &nbsp; ...state,&nbsp; &nbsp; [btnId]: !state[btnId],&nbsp; }));};完整代码function Mata() {&nbsp; const [activeTab, setActiveTab] = useState("activeTab");&nbsp; const [isBlack, setIsBlack] = useState({});&nbsp; const handleBtn = btnId => e => {&nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; setIsBlack(state => ({&nbsp; &nbsp; &nbsp; ...state,&nbsp; &nbsp; &nbsp; [btnId]: !state[btnId]&nbsp; &nbsp; }));&nbsp; };&nbsp; return (&nbsp; &nbsp; <div className="container">&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack["btn1"] ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn1 ${isBlack["btn1"] && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn("btn1")}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn1&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack["btn2"] ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn2 ${isBlack["btn2"] && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn("btn2")}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn2&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack["btn3"] ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn3 ${isBlack["btn3"] && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn("btn3")}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn3&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack["btn4"] ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn4 ${isBlack["btn4"] && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn("btn4")}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn4&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack["btn5"] ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn5 ${isBlack["btn5"] && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn("btn5")}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn5&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; </div>&nbsp; );}有很多重复的代码,所以一个更干的版本,其中活动选项卡和按钮作为道具传递。function Mata({ activeTab = '', buttons }) {&nbsp; const [isBlack, setIsBlack] = useState({});&nbsp; const handleBtn = btnId => e => {&nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; setIsBlack(state => ({&nbsp; &nbsp; &nbsp; ...state,&nbsp; &nbsp; &nbsp; [btnId]: !state[btnId]&nbsp; &nbsp; }));&nbsp; };&nbsp; return (&nbsp; &nbsp; <div className="container">&nbsp; &nbsp; &nbsp; {buttons.map(btn => (&nbsp; &nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack[btn] ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className={`btn1 ${isBlack[btn] && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn(btn)}&nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {btn}&nbsp; &nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; ))}&nbsp; &nbsp; </div>&nbsp; );}像这样使用const buttons = ["btn1", "btn2", "btn3", "btn4", "btn5"];...<Mata buttons={buttons} />编辑似乎你真的在创建一个“标签管理器”。我建议将状态放样到父级并转换Mata为只呈现“选项卡”按钮的“哑”组件。采用 3 个道具:活动选项卡索引、按钮数组和状态更新回调。function Mata({ activeTab = -1, buttons, setActiveTab }) {&nbsp; return (&nbsp; &nbsp; <div className="container">&nbsp; &nbsp; &nbsp; {buttons.map((btn, i) => {&nbsp; &nbsp; &nbsp; &nbsp; const isActive = i === activeTab;&nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; key={btn.id}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isActive ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className={`${btn.id} ${isActive && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={() => setActiveTab(i)}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {btn.id}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; })}&nbsp; &nbsp; </div>&nbsp; );}示例选项卡数据const tabs = [&nbsp; { id: "btn1", data: "data1" },&nbsp; { id: "btn2", data: "data2" },&nbsp; { id: "btn3", data: "data3" },&nbsp; { id: "btn4", data: "data4" },&nbsp; { id: "btn5", data: "data5" }];用法示例<Mata activeTab={activeTab} buttons={tabs} setActiveTab={setActiveTab} />{activeTab === -1 ? (&nbsp; <div>Social Media</div>) : (&nbsp; <div>{tabs[activeTab].data}</div>)}添加“图标”类似于在运行时选择类型如果 SVG 图标还不是反应组件,将它们包装成一个简单的功能组件const Icon1 = () => <svg>...</svg>;在标签数据中添加一个图标字段并将值设置为图标组件const tabs = [&nbsp; { id: "btn1", data: "data1", icon: Icon1 },&nbsp; { id: "btn2", data: "data2", icon: Icon2 },&nbsp; { id: "btn3", data: "data3", icon: Icon3 },&nbsp; { id: "btn4", data: "data4", icon: Icon4 },&nbsp; { id: "btn5", data: "data5", icon: Icon5 }];并解构并重命名以呈现function Mata({ activeTab = -1, buttons, setActiveTab }) {&nbsp; return (&nbsp; &nbsp; <div className="container">&nbsp; &nbsp; &nbsp; {buttons.map((btn, i) => {&nbsp; &nbsp; &nbsp; &nbsp; const isActive = i === activeTab;&nbsp; &nbsp; &nbsp; &nbsp; const { icon: Icon, id } = btn; // <-- rename icon -> Icon&nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; key={id}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isActive ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; className={`${id} ${isActive && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={() => setActiveTab(i)}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Icon /> {id} // <-- render icon component&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; })}&nbsp; &nbsp; </div>&nbsp; );}

BIG阳

你为什么做这个const [isBlack, setIsBlack] = useState(0);而不是这样做?const [isBlack, setIsBlack] = useState(false);另外,要使用 useState,您必须像下面这样编辑代码,因为挂钩只能在函数组件的主体内部调用。import React, { useState, useEffect, useRef } from "react";function Mata() {&nbsp; const [isBlack, setIsBlack] = useState(false); // correction here&nbsp; const handleBtn1 = e => {&nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; setIsBlack(!isBlack);&nbsp; };&nbsp; const handleBtn2 = e => {&nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; setIsBlack(!isBlack);&nbsp; };&nbsp; const handleBtn3 = e => {&nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; setIsBlack(!isBlack);&nbsp; };&nbsp; const handleBtn4 = e => {&nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; setIsBlack(!isBlack);&nbsp; };&nbsp; const handleBtn5 = e => {&nbsp; &nbsp; e.preventDefault();&nbsp; &nbsp; setIsBlack(!isBlack);&nbsp; };&nbsp; return (&nbsp; &nbsp; <div className="container">&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn1 ${isBlack && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn1}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn1&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn2 ${isBlack && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn2}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn2&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn3 ${isBlack && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn3}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn3&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn4 ${isBlack && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn4}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn4&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; &nbsp; <button&nbsp; &nbsp; &nbsp; &nbsp; style={{ backgroundColor: isBlack ? "#262626" : "#F3F3F3" }}&nbsp; &nbsp; &nbsp; &nbsp; className={`btn5 ${isBlack && activeTab}`}&nbsp; &nbsp; &nbsp; &nbsp; onClick={handleBtn5}&nbsp; &nbsp; &nbsp; >&nbsp; &nbsp; &nbsp; &nbsp; btn5&nbsp; &nbsp; &nbsp; </button>&nbsp; &nbsp; </div>&nbsp; );}export default Mata;
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript