【发布时间】:2020-10-02 13:53:09
【问题描述】:
我正在尝试将选定状态添加到我的按钮,我遇到的问题是每次单击它时,当我只想更新单击的按钮时,它会更新每个按钮的状态。
此应用的工作方式是,当您添加书签时,按钮文本会从“添加”变为“已添加”,同时还会更改类别。
这是我的按钮组件
import React from "react";
import PropTypes from "prop-types";
const Button = ({ children, onClick, classname }) => {
return (
<button onClick={onClick} className={classname}>
<span>{children}</span>
</button>
);
};
Button.propTypes = {
children: PropTypes.any.isRequired,
onClick: PropTypes.func.isRequired,
classname: PropTypes.string.isRequired
};
export default Button;
这是我的卡片组件,这是使用按钮的地方。
import React, { useState } from "react";
import PropTypes from "prop-types";
import "../css/Card.scss";
import { useStyles } from "../cssInJs/buttonStyle";
import Button from "./Button";
function Card({ author, title, image, onClick, selected }) {
const classes = useStyles();
return (
<div className="Card__item">
<div className="Card__spacer">
<span className="Card__item__authorStyle">{author}</span>
</div>
<div>
<span className="Card__item__titleStyle">{title}</span>
</div>
<div>
<Button
classname={`${selected ? classes.selectedButton : classes.myButton}`}
onClick={onClick}
>
{` ${selected ? "ADDED" : "ADD"}`}
</Button>
</div>
<div className="Card__item__image">
<img src={image} alt="article-img" />
</div>
</div>
);
}
Card.propTypes = {
author: PropTypes.string.isRequired,
title: PropTypes.string.isRequired
};
export default Card;
最后,这两个组件在布局组件中相遇:
import React, { useState } from "react";
import useFetch from "../hooks/useFetch";
import "../css/Layout.scss";
import Card from "./Card";
import BookmarksBar from "./BookmarksBar";
function Layout() {
const { response } = useFetch();
console.log(response);
const [bookmarks, setBookmarks] = useState([]);
const [selectedButton, setSelectedButton] = useState(false);
function handleAddBookMark(title) {
if (!bookmarks.includes(title)) {
setBookmarks([...bookmarks, title]);
setSelectedButton(true);
} else {
return false;
}
}
function handleRemoveBookmark(val) {
var index = bookmarks.indexOf(val);
if (index > -1) {
setBookmarks(bookmarks => bookmarks.filter((img, i) => i !== index));
}
}
if (!response || response.length === 0) {
return <div> Loading...</div>;
} else {
return (
<div className="Layout__container">
<div className="Layout__container__mainColumn">
{response.data.articles.map((article, i) => (
<Card
key={i}
author={article.author}
title={article.title}
image={article.urlToImage}
onClick={() => handleAddBookMark(article.title)}
selected={selectedButton}
/>
))}
</div>
<div className="Layout__container__rightColumn">
<div className="Layout__container__rightColumn__customHr" />
<div className="Layout__container__rightColumn__bookmarks">
<span>Your bookmarks</span>
<p>Articles you bookmark will be added to this list</p>
</div>
<BookmarksBar data={bookmarks} onClick={handleRemoveBookmark} />
</div>
</div>
);
}
}
export default Layout;
按钮状态由selectedButton 值控制。每次我单击由handleAddBookmark 函数触发的按钮时,它会将selectedButton 设置为true,但问题是当我只希望单击的按钮为true 时,它会将列表中的每个按钮设置为真.我如何做到这一点?
【问题讨论】:
-
您有一个值,用于跟踪是否选择了多个值之一。那是你的问题。也许相反, selected 应该是一个包含所选项目 id 的数组?然后,当您选择时,将 id 添加到数组中,否则删除。然后在你的按钮选择的道具中,你可以像
selected.includes(item.id) -
@RogerBanks 您是否要求您的 Card 组件为任何 setSelected 更新一次又一次地重新渲染?如果是这样,那是因为
handleAddBookMark方法被作为道具传递,而没有被缓存。您可以使用useCallback来解决此问题。 -
有道理.. szczocik 可以提供一个例子吗?
标签: reactjs