简体   繁体   English

React组件function调用只更新一个组件实例

[英]React component function call only updates one component instance

I have a component called RightTab like this我有一个像这样的名为RightTab的组件

const RightTab = ({ data }) => {
  return (
    <div className="RightTab flex__container " onClick={data.onClick}>
      <img src={data.icon} alt="Dashboard Icon" />
      <p className="p__poppins">{data.name}</p>
      {data.dropDown === true ? (
        <div className="dropdown__icon">
          <img src={Assets.Arrow} alt="Arrow" />
        </div>
      ) : (
        <div className="nothing"></div>
      )}
    </div>
  );
};

export default RightTab;

The tab has an active state in its CSS like this该选项卡在其 CSS 中有一个活动的 state ,如下所示

.RightTab.active {
  background-color: var(--primaryGreen);
}

as you have seen it changes the color when an active class is added.如您所见,添加活动 class 时它会更改颜色。 I have an array in the parent component that I pass down to the child component as props.我在父组件中有一个数组,我将它作为道具传递给子组件。 Here is the array这是数组

const dataArray = [
  {
    name: "Dashboard",
    icon: Assets.Dashboard,
    dropDown: false,
    onClick: handleDashBoardClick,
  },
  {
    name: "Inventory",
    icon: Assets.Inventory,
    dropDown: true,
    onClick: handleInventoryClick,
  },
  {
    name: "Reports",
    icon: Assets.Reports,
    dropDown: true,
    onClick: handleReportsClick,
  },
];

Here is how I pass the props down.这是我传递道具的方式。

  <RightTab data={dataArray[0]} />
  <RightTab data={dataArray[1]} />
  <RightTab data={dataArray[2]} />

The data prop passed into the component is an object containing a function call as one of its properties like this.传递到组件中的数据属性是一个 object,其中包含一个 function 调用作为其属性之一,如下所示。 I have an onclick attribute on the child components' main container that is supposed to call the respective function.我在子组件的主容器上有一个onclick 属性,它应该调用相应的 function。

The function is what adds the active class to make the background change color. function 是添加活动 class以使背景改变颜色。 However each time I click on the component it only changes the background of the first occurrence .但是,每次我单击该组件时,它只会更改第一次出现的背景 And as you may have noticed I call the component thrice.正如您可能已经注意到的那样,我三次调用该组件。 No matter which component I click only the first ones background changes .无论我点击哪个组件,只有第一个背景发生变化

Here is an example of the function that is on the prop object.这是 object 上的 function 的示例。

const handleDashBoardClick = () => {
  const element = document.querySelector(".RightTab");
  element.classList.toggle("active");
};

I don't get what I'm doing wrong.我不明白我做错了什么。 What other approach can I use?我还可以使用什么其他方法?

Although you use the component 3 times, it doesn't mean that a change you make in one of the components will be reflected in the other 2, unless you specifically use a state parameter that is passed to all 3 of them.虽然您使用该组件 3 次,但这并不意味着您对其中一个组件所做的更改会反映在其他两个组件中,除非您专门使用传递给所有三个组件的 state 参数。

Also, the way you add the active class is not recommended since you mix react with pure js to handle the CSS class names.此外,不推荐添加活动 class 的方式,因为您将反应与纯 js 混合来处理 CSS class 名称。

I would recommend having a single click handler that toggles the active class for all n RightTab components:我建议使用一个单击处理程序来切换所有n RightTab组件的活动 class:

const MainComponent = () => {
  const [classNames, setClassNames] = useState([]);
  
  const handleClick = (name) => 
  {
    const toggledActiveClass = classNames.indexOf('active') === -1
      ? classNames.concat(['active'])
      : classNames.filter((className) => className !== 'active');
      
    setClassNames(toggledActiveClass);
    
    switch (name) {
      case 'Dashboard';
        // do something
        break;
        
        case 'Inventory':
        // ....
        break;
    }
  }
  
  const dataArray = [
    {
      name: "Dashboard",
      icon: Assets.Dashboard,
      dropDown: false,
      onClick: handleClick.bind(null, 'Dashboard'),
    },
    {
      name: "Inventory",
      icon: Assets.Inventory,
      dropDown: true,
      onClick: handleClick.bind(null, 'Inventory'),
    },
    {
      name: "Reports",
      icon: Assets.Reports,
      dropDown: true,
      onClick: handleClick.bind(null, 'Reports'),
    },
  ];

  return (
    <>
      {dataArray.map((data) => 
        <RightTab key={data.name} 
                  data={data} 
                  classNames={classNames} />)}
    </>
  );
};

const RightTab = ({ data, classNames }) => {
  return (
    <div className={classNames.concat(['RightTab flex__container']).join(' ')} 
         onClick={data.onClick}>
      <img src={data.icon} alt="Dashboard Icon" />
      <p className="p__poppins">{data.name}</p>
      {data.dropDown === true ? (
        <div className="dropdown__icon">
          <img src={Assets.Arrow} alt="Arrow" />
        </div>
      ) : (
        <div className="nothing"></div>
      )}
    </div>
  );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM