我正在开发一个联系人列表应用程序。基本上使用几个个人/人的材料用户界面列表。这是一个粗略的概述:
PersonListItem --- 子组件:包含卡片上显示的所有人员详细信息 PersonList -- 父组件:基本上是通过所有的人进行映射并将所有卡片显示为列表
最近,我为每张卡片添加了一个星星组件,想法是如果我想将一个人标记为最喜欢的人,那么我会点击星星,它会变成黄色。
为了实现这一点,我学习并实现了 React 的lift-state-up with hooks 模式。所以现在的流程是这样的:
Child Component => onClick = {someMethod} => someMethod passed as props to Parent => Parent updates prop component => Child re-renders the component
但是现在当我点击任何一个联系人的星星标记收藏时,所有联系人都被标记为收藏。
我想使用 event.target 来获取单个明星的 id 但如何在道具中传递和访问 event.target.id ?
这是我当前的代码:
const PersonListItem = (props) {
const{person, onSelectChanged, favorite, FavColorColor, markFavorite} = props;
return(
<ListItem button
gender = {undefined}
onClick = {onSelectChanged}
<Avatar className = {classes.avatar} src={person.imageLocation === NO_USER_IMAGE : null : person.imageLocation}>
<IconButton StarOutLinedIcon onClick = {markFavorite} style={{backgroundColor: `${FavColor}`}/>
<ListItemText primary =
{
{person.name}
}
secondary = {<div className={classes.smallText}>{person.company}{person.jobTitle}</div>/>
</ListItem>
)
}
export default PersonListItem;
const PersonList = (props) => {
const[favorite, setFavorite] = useState(0);
const[FavColor, setColor] = useState(' ');
const markFavorite = (value) => {
setFavorite(value = !value);
{!favorite ? setColor("yellow") : setColor(" ")}
}
return(
<div className={classes.root}>
<MuiList className={props.className} isLoading={isLoading}>
{
!isLoading && person
.map((person, index) => {
return <PersonListItem key={index}
person = {person}
onSelectChanged = () =>{
HideAdd();
}
markFavorite = {markFavorite} FavColorColor = {FavColor}/>
}
}
</MuiList>
</div>
)
}
export default PersonList;
//Material UI ListItem
classs MuiList extends React.Component{
componentDidMount() {
i(this.props.fetch)
{
this.props.fetch();
}
}
render() {
const attributes = {...this.props};
delete attributes.isLoading;
delete attributes.fetch;
delete attributes.fetchData;
const items = this.props.isLoading;
? <ListItem key={0}>
<CircularProgress/>
<ListItemText primary='Loading...'/>
</ListItem>
: this.props.children;
return <List {...attributes>{items}</List>
}
}
export default MuiList;
答案 0 :(得分:2)
我会用个人 ID 替换一个对象的最喜欢的状态,如果它们是真或假,就会映射。还删除 favColor
状态。它是从收藏夹派生的状态,您不需要此状态。
现在,我将更改 markFavorite 函数(可能将名称更改为 toggleFavorite
)。它会从那个人那里收到一个 id。它检查它是否在 favorites
中;如果未定义,则键尚不存在,因此将其标记为收藏),否则仅切换其值:
const[favorites, setFavorites] = useState({});
const markFavorite = (id) => {
setFavorites(prevFavorites => {
const favorites = { ...prevFavorites }
favorites[id] = favorites[id] === undefined || !favorites[id]
return favorites
})
}
然后在您的个人映射中,我会将 markFavorite
作为传递 person.id
的箭头函数传递(这里我假设 person 有一个 id,这比从您的地图传递索引要好)。
还传递带有 isFavorite
布尔值的 favorites[person.id]
(!!
返回布尔值。实际上不需要 !!
,因为 undefined
解析为 false ,更多是为了一致性类型)
markFavorite={() => markFavorite(person.id)} isFavorite={!!favorites[person.id]}/>
在您的 PersonListItem
处,您必须将 IconButton 样式定义更改为三元条件:
<IconButton StarOutLinedIcon onClick = {markFavorite} style={{backgroundColor: isFavorite ? 'yellow' : '' }}/>
这样每个人都可以独立标记,不影响其他人。