Как я могу удалить активный класс на каждом дочернем компоненте, в то же время устанавливая его активным для выбранного ребенка? - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь установить активный класс на дочернем компоненте B, отключая активный класс на дочернем компоненте A, когда нажимаю B. B. 1001 *

До сих пор я пытался использовать хуки в родительском классе, где я отключилактивная поддержка на всех дочерних элементах с помощью 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 был функцией навигации, все, что я изменил, - это установил onClick в родительском элементе для навигации и получил вызов функции навигации setActive, используя id в качестве параметра и вызвав setActive в функции навигации с id в качестве параметра снова.Классы теперь выглядят так:

Родитель:

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>
  );
}

Ответы [ 3 ]

0 голосов
/ 02 мая 2019

(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' />
0 голосов
/ 02 мая 2019

Передача setActive в NavLinks.При нажатии NavLink он устанавливает id через setActive.Каждый элемент также получает свойство isActive, которое равно true, если состояние active соответствует его id.

.

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>
0 голосов
/ 02 мая 2019

Я думаю, что у меня будет запись состояния в родительском элементе, такая как whichIsActive, и я дам ей свойство set активной ссылки с помощью функции onclick, например, индекса.

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

Тогда в вашем className вы можете сделать что-то вроде className=${this.state.whichIsActive === index && 'active'} (не забывая `вокруг). Я не проверял это, но я думаю, что это должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...