在将每个孩子组件设置为“单击儿童”的活动时,我如何在每个孩子组件上启动一个活动类



我正在尝试在子组件B上设置一个活动类,而我单击b。

到目前为止,我已经尝试在父类中使用钩子,在该钩子中,我通过使用setActive('');,然后使用e.currentTarget.className === 'link--active' ? e.currentTarget.className = '' : e.currentTarget.className = 'link--active';将当前目标的类设置为链接 - 将当前目标的类设置为链接。可悲的是,目前所做的一切只是添加课程或删除单击孩子上的课程。

父母:

  const [active, setActive] = useState('');
  const navigate = (e) => {
    setActive('');
    e.currentTarget.className === 'link--active' ? e.currentTarget.className = '' : e.currentTarget.className = 'link--active';
  };

和返回语句中:

{menuItems.map((item, index) => (
  <li key={index} >
    <NavLink target={item} onClick={(e) => navigate(e)} active={active} />
  </li>
))}

孩子:

<a href="#"
   onClick={props.onClick} 
   className={props.active}>
   {props.target}
</a>

编辑:

使用ORI DRORI的解决方案后,将活动类设置在单击的NAVLink上,然后从其余部分中删除。由于我希望onclick成为导航函数,因此我更改的只是将父级设置为导航,并通过使用ID AS PARAM和将setActive在导航函数中进行导航,并在导航函数中呼叫setActive,并再次使用ID作为param。现在的课程看起来像这样:

父母:

const [active, setActive] = useState(null);
const navigate = (id) => {
  setActive(id);
};
return (
    {menuItems.map((item) => (
      <li key={item.id} >
        <NavLink 
          {...item}
          isActive={active === item.id}
          onClick={navigate} />
      </li>
    ))}
)

儿童:

const NavLink = ({id, target, isActive, onClick}) => {
  return (
      <a href="#"
        onClick={useCallback(() => onClick(id), [id, onClick])} 
        className={isActive ? 'active' : ''}>
        {target}
      </a>
  );
}

setActive传递到navlinks。单击NavLink时,它通过setActive设置其id。每个项目还接收isActive属性,如果active状态与id匹配,则为true

const { useCallback, useState } = React
const NavLink = ({ id, target, isActive, onClick }) => (
  <a href="#"
     onClick={useCallback(() => onClick(id), [id])} 
     className={`navLink ${isActive ? 'active' : ''}` }>
     {target}
  </a>
)
const Parent = ({ menuItems }) => {
  const [active, setActive] = useState(null);
  return (
    <ul>
      {menuItems.map((item) => (
        <li key={item.id} >
          <NavLink 
            {...item} 
            onClick={setActive} 
            isActive={active === item.id} />
        </li>
      ))}
    </ul>
  )
}
const items = [{ id: 0, target: 'Ready' }, { id: 1, target: 'Player' }, { id: 2, target: 'One' }]
ReactDOM.render(
  <Parent menuItems={items} />,
  demo
)
.navLink {
  color: blue;
  text-decoration: none;
}
.active {
  color: red;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="demo"></div>

(1( Assign an id to each of child components
(2( Add inactive class to all child components
(3( Remove inactive class from selected component and add active class to it
这是您问题的工作解决方案。我希望它有帮助。

class App extends React.Component {
  state = {
    childComponents: [
      { id: "ironman", component: <IronMan /> },
      { id: "captainamerica", component: <CaptainAmerica /> },
      { id: "thor", component: <Thor /> },
      { id: "loki", component: <Loki /> },
      { id: "spiderman", component: <Spiderman /> }
    ],
    currComponentId: ""
  };
  clickHandler = idComponent => {
    // get access to all classes
    if (this.state.currComponentId !== "")
      document
        .getElementById(this.state.currComponentId)
        .classList.remove("active");
    let element = document.getElementsByClassName("child-components");
    for (let index = 0; index < element.length; index++) {
      element[index].classList.add("inactive");
    }
    document.getElementById(idComponent).classList.remove("inactive");
    document.getElementById(idComponent).classList.add("active");
    this.setState({ currComponentId: idComponent });
  };
  render() {
    return (
      <div className="parent">
        <ul>
          {this.state.childComponents.map(element => {
            return (
              <li>
                <button
                  id={element.id}
                  className="child-components"
                  onClick={() => this.clickHandler(element.id)}
                >
                  {element.id}
                </button>
                {this.state.currComponentId === element.id ? (
                  <span> Active component</span>
                ) : null}
              </li>
            );
          })}
        </ul>
        <div>
          {this.state.childComponents.map(element => {
            if (element.id === this.state.currComponentId)
              return <div>{element.component}</div>;
          })}
        </div>
      </div>
    );
  }
}
const IronMan = () => <div>This is IronMan Component</div>;
const CaptainAmerica = () => <div>This is CaptainAmerica Component</div>;
const Thor = () => <div>This is Thor Component</div>;
const Loki = () => <div>This is Loki Component</div>;
const Spiderman = () => <div>This is Spiderman Component</div>;
ReactDOM.render(<App/>, document.getElementById('root'));
.active {
  border: solid 1px red;
  background-color: black;
  color: #fff;
}
.inactive {
  color: #000;
  background-color: #fff;
}
.parent{
 border: solid 1px #322f31;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root' />

我想我会在诸如 whichIsActive之类的父级中有一个状态条目,并将其设置为带有onclick函数的活动链接的设置属性,例如索引。

const navigate = (index) => {
this.setState{(whichIsActive: index)}
 };

然后,在您的className中,您可以执行诸如className=${this.state.whichIsActive === index && 'active'}之类的操作(而不忘记周围的``周围''。我尚未测试它,但我认为它应该起作用。

最新更新