如何在每个 child 组件上取消设置活动 class,同时将其设置为针对单击的 child 活动
How can I unset an active class on each child component while setting it to active for the clicked child
我正在尝试在 child 组件 B 上设置活动 class,同时在单击 B 时禁用 child 组件 A 上的活动 class。
到目前为止,我已经尝试在 parent class 中使用钩子,我通过使用 setActive('');
然后设置 [=取消所有 child 上的活动道具=42=] 的当前目标到 link-- 使用 e.currentTarget.className === 'link--active' ? e.currentTarget.className = '' : e.currentTarget.className = 'link--active';
激活。遗憾的是,此时它所做的只是在单击的 child.
上添加 class 或删除 class
Parent:
const [active, setActive] = useState('');
const navigate = (e) => {
setActive('');
e.currentTarget.className === 'link--active' ? e.currentTarget.className = '' : e.currentTarget.className = 'link--active';
};
并在 return 语句中:
{menuItems.map((item, index) => (
<li key={index} >
<NavLink target={item} onClick={(e) => navigate(e)} active={active} />
</li>
))}
Child仁:
<a href="#"
onClick={props.onClick}
className={props.active}>
{props.target}
</a>
编辑:
在使用 Ori Drori 的解决方案后,活动的 class 被设置在点击的 NavLink 上并从其余的移除。因为我希望 onClick 成为导航函数,所以我所做的所有更改都是将 parent 中的 onClick 设置为导航,并通过使用 id 作为参数并在导航函数中调用 setActive 来调用导航函数 setActive 并将 id 作为再次参数。 classes 现在看起来像这样:
Parent:
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>
))}
)
Child:
const NavLink = ({id, target, isActive, onClick}) => {
return (
<a href="#"
onClick={useCallback(() => onClick(id), [id, onClick])}
className={isActive ? 'active' : ''}>
{target}
</a>
);
}
我想我会在父级中有一个状态条目,例如 whichIsActive
,并给它一个带有 onclick 函数的活动 link 的集合 属性,例如索引例子。
const navigate = (index) => {
this.setState{(whichIsActive: index)}
};
然后在你的 className 中你可以做类似 className=${this.state.whichIsActive === index && 'active'}
的事情(不要忘记周围的 `)。我没有测试过它,但我认为它应该可以工作。
(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' />
将 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>
我正在尝试在 child 组件 B 上设置活动 class,同时在单击 B 时禁用 child 组件 A 上的活动 class。
到目前为止,我已经尝试在 parent class 中使用钩子,我通过使用 setActive('');
然后设置 [=取消所有 child 上的活动道具=42=] 的当前目标到 link-- 使用 e.currentTarget.className === 'link--active' ? e.currentTarget.className = '' : e.currentTarget.className = 'link--active';
激活。遗憾的是,此时它所做的只是在单击的 child.
Parent:
const [active, setActive] = useState('');
const navigate = (e) => {
setActive('');
e.currentTarget.className === 'link--active' ? e.currentTarget.className = '' : e.currentTarget.className = 'link--active';
};
并在 return 语句中:
{menuItems.map((item, index) => (
<li key={index} >
<NavLink target={item} onClick={(e) => navigate(e)} active={active} />
</li>
))}
Child仁:
<a href="#"
onClick={props.onClick}
className={props.active}>
{props.target}
</a>
编辑:
在使用 Ori Drori 的解决方案后,活动的 class 被设置在点击的 NavLink 上并从其余的移除。因为我希望 onClick 成为导航函数,所以我所做的所有更改都是将 parent 中的 onClick 设置为导航,并通过使用 id 作为参数并在导航函数中调用 setActive 来调用导航函数 setActive 并将 id 作为再次参数。 classes 现在看起来像这样:
Parent:
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>
))}
)
Child:
const NavLink = ({id, target, isActive, onClick}) => {
return (
<a href="#"
onClick={useCallback(() => onClick(id), [id, onClick])}
className={isActive ? 'active' : ''}>
{target}
</a>
);
}
我想我会在父级中有一个状态条目,例如 whichIsActive
,并给它一个带有 onclick 函数的活动 link 的集合 属性,例如索引例子。
const navigate = (index) => {
this.setState{(whichIsActive: index)}
};
然后在你的 className 中你可以做类似 className=${this.state.whichIsActive === index && 'active'}
的事情(不要忘记周围的 `)。我没有测试过它,但我认为它应该可以工作。
(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' />
将 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>