3 Вопрос: Как я могу удалить активный класс на каждом дочернем компоненте, в то же время устанавливая его активным для выбранного ребенка?

вопрос создан в Thu, May 2, 2019 12:00 AM

Я пытаюсь установить активный класс на дочернем компоненте B, отключая активный класс на дочернем компоненте A, когда нажимаю на 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>

Edit:

После использования решения от 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>
  );
}
    
0
3 ответа                              3                         

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

р>

id
    
0
2019-05-02 17: 44: 41Z
  1. Спасибо за ответ, в настоящее время он работает, однако следующая проблема, с которой я сталкиваюсь, заключается в том, что каждая навигационная ссылка теперь вызывает setActive вместо навигации, в которой также используется setActive. называется. Можно ли вызвать навигацию, которая в свою очередь вызовет setActive?
    2019-05-03 13: 04: 03Z
  2. Не берите в голову, я нашел решение, я опубликую его в редактировании
    2019-05-03 13: 21: 41Z

(1)

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>

(2) Assign an id to each of child components
(3) Add inactive class to all child components.
Это рабочее решение для вашего вопроса. Надеюсь, это поможет.

р>

Remove inactive class from selected component and add active class to it
    
0
2019-05-02 15: 44: 50Z

Я думаю, что у меня будет запись состояния в родительском элементе, например,

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' />
, и я назначу ей свойство set активной ссылки с помощью функции onclick, например, индекса. whichIsActive

Затем в вашем className вы можете сделать что-то вроде

const navigate = (index) => {
this.setState{(whichIsActive: index)}
 };
(не забывая `вокруг). Я не проверял это, но я думаю, что это должно работать.     
0
2019-05-02 15: 48: 35Z
className=${this.state.whichIsActive === index && 'active'}
источник размещен Вот