单击时在映射元素上反应切换样式
React toggle style on mapped element on click
这里是 React 新手。一个非常简单的事情,我似乎做不对。
我想更改我地图中单击的元素上的 class,而不是全部。
例如,如果我单击 id 为 1 的元素,它的 class 应该为 'active-color'。如果我然后单击 id 为 2 的元素,则该元素应采用 class 'active-color',而 id 1 应 not 不再具有此 class .
我尝试了很多不同的解决方案,但似乎无法解决这个问题。它似乎不喜欢我在这里使用我的处理函数中的钩子和 returns 一个错误:TypeError: setActive is not a function.
任何想法或其他解决方案将不胜感激!
const ListItems = () => {
const { isActive, setActive} = useState(false)
const { item, dispatch } = useContext(AppContext);
const handler = (event) => {
dispatch({
type: 'SET_ITEM',
payload: event.currentTarget.dataset.index,
});
setActive(!isActive);
};
return (
<div className="container">
<h2 className="smallheader">Please choose one</h2>
<div className="flex flex-center">
{ITEMS.map((item) =>
<div className={isActive ? 'active-color' : 'card'} data-index={item.value} key={item.id} onClick={handler}>
<span
className="card-header">{item.name}</span>
<span className="card-description">{item.description}</span>
</div>
)}
</div>
</div>
)
};
export default ListItems;
您的第一个问题是 useState()
returns 一个数组,而不是一个对象。这意味着当你 destructure isActive
和 setIsActive
你需要使用数组解构 []
:
const [isActive, setActive] = useState(false);
根据您的 AppContext
设置方式,您可能还需要对项目和分派使用数组解构。您的下一个问题是上述状态仅存储布尔值。如果为真,则映射时渲染的每个值都将为 true
。这意味着当 active 设置为 true 时,所有项目都将应用 active class。为了帮助管理这一点,您可以更改状态值以保存活动项目的 ID。然后在你的映射回调函数中,检查当前item id是否与你state中存储的id匹配,如果匹配,使用active-color
class,否则使用card
class.
const [activeItem, setActiveItem] = useState(-1);
const handler = (itemId) => {
dispatch({ // you may want to conditionally call this, but I'm basing it off your current logic
type: 'SET_ITEM',
payload: itemId,
});
setActiveItem(currentItem => currentItem === -1 ? itemId : -1); // toggle between -1 and itemPressed to make active state toggleable
};
return (
<div className="container">
<h2 className="smallheader">Please choose one</h2>
<div className="flex flex-center">
{ITEMS.map((item) =>
<div className={activeItem === item.id ? 'active-color' : 'card'} key={item.id} onClick={() => handler(item.id)}>
...
数组解构需要方括号:
而不是:
const { isActive, setActive} = useState(false)
const { item, dispatch } = useContext(AppContext);
写入:
const [ isActive, setActive] = useState(false)
const [ item, dispatch ] = useContext(AppContext);
这里是 React 新手。一个非常简单的事情,我似乎做不对。
我想更改我地图中单击的元素上的 class,而不是全部。
例如,如果我单击 id 为 1 的元素,它的 class 应该为 'active-color'。如果我然后单击 id 为 2 的元素,则该元素应采用 class 'active-color',而 id 1 应 not 不再具有此 class .
我尝试了很多不同的解决方案,但似乎无法解决这个问题。它似乎不喜欢我在这里使用我的处理函数中的钩子和 returns 一个错误:TypeError: setActive is not a function.
任何想法或其他解决方案将不胜感激!
const ListItems = () => {
const { isActive, setActive} = useState(false)
const { item, dispatch } = useContext(AppContext);
const handler = (event) => {
dispatch({
type: 'SET_ITEM',
payload: event.currentTarget.dataset.index,
});
setActive(!isActive);
};
return (
<div className="container">
<h2 className="smallheader">Please choose one</h2>
<div className="flex flex-center">
{ITEMS.map((item) =>
<div className={isActive ? 'active-color' : 'card'} data-index={item.value} key={item.id} onClick={handler}>
<span
className="card-header">{item.name}</span>
<span className="card-description">{item.description}</span>
</div>
)}
</div>
</div>
)
};
export default ListItems;
您的第一个问题是 useState()
returns 一个数组,而不是一个对象。这意味着当你 destructure isActive
和 setIsActive
你需要使用数组解构 []
:
const [isActive, setActive] = useState(false);
根据您的 AppContext
设置方式,您可能还需要对项目和分派使用数组解构。您的下一个问题是上述状态仅存储布尔值。如果为真,则映射时渲染的每个值都将为 true
。这意味着当 active 设置为 true 时,所有项目都将应用 active class。为了帮助管理这一点,您可以更改状态值以保存活动项目的 ID。然后在你的映射回调函数中,检查当前item id是否与你state中存储的id匹配,如果匹配,使用active-color
class,否则使用card
class.
const [activeItem, setActiveItem] = useState(-1);
const handler = (itemId) => {
dispatch({ // you may want to conditionally call this, but I'm basing it off your current logic
type: 'SET_ITEM',
payload: itemId,
});
setActiveItem(currentItem => currentItem === -1 ? itemId : -1); // toggle between -1 and itemPressed to make active state toggleable
};
return (
<div className="container">
<h2 className="smallheader">Please choose one</h2>
<div className="flex flex-center">
{ITEMS.map((item) =>
<div className={activeItem === item.id ? 'active-color' : 'card'} key={item.id} onClick={() => handler(item.id)}>
...
数组解构需要方括号:
而不是:
const { isActive, setActive} = useState(false)
const { item, dispatch } = useContext(AppContext);
写入:
const [ isActive, setActive] = useState(false)
const [ item, dispatch ] = useContext(AppContext);