【发布时间】:2019-12-08 01:08:21
【问题描述】:
每次我展开特定的卡片时,所有角色卡片都会展开,而我只想要特定的卡片。我正在使用星球大战 api,使用 react-hooks 和 material-ui。
据我所知和阅读,我能够通过 handleClick() 事件传递索引,但在 handleClick 函数本身中我迷路了。我尝试将索引附加到展开状态,但我会收到一条错误消息,指出我无法将数字附加到布尔值。我也明白分离组件和映射可能是解决方案,这是有道理的,但我无法做到。已经有几天了,所以现在我尽可能寻求帮助。谢谢。
app.js 文件
const [loading, setLoading] = useState(false);
const [data, setData] = useState([]);
useEffect(() => {
setLoading(true);
const fetchData = async () => {
try {
const result = await axios.get("https://swapi.co/api/people/");
setLoading(false);
// console.log(result.data.results);
setData(result.data.results);
} catch (error) {
console.log("there was an error");
}
};
fetchData();
}, []);
return (
<div className="App">
<CssBaseline />
<Typography variant="h1">React Wars</Typography>
<Icon>star</Icon>
<MediaCard data={data} />
</div>
);
};
export default App;
card.js 文件
const useStyles = makeStyles(theme => ({
card: {
width: 200,
marginBottom: 16
},
media: {
height: 0,
paddingTop: "56.25%" // 16:9
},
expand: {
transform: "rotate(0deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest
})
},
expandOpen: {
transform: "rotate(180deg)"
},
avatar: {
backgroundColor: red[500],
margin: 0
},
card_container: {
display: "flex",
maxWidth: 1064,
flexWrap: "wrap",
margin: "auto",
justifyContent: "space-between"
}
}));
const classes = useStyles();
const [expanded, setExpanded] = React.useState(false);
function handleExpandClick(index) {
setExpanded(!expanded);
}
const a = props.data.map((data, index) => {
return (
<Card className={classes.card} key={index}>
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
marginTop: 16
}}
>
<Avatar aria-label="recipe" className={classes.avatar}>
{data.name.charAt(0)}
</Avatar>
{
<Typography variant="h5" key={index} style={{ margin: "8px auto" }}>
{data.name}
</Typography>
}
</div>
<IconButton
className={clsx(classes.expand, {
[classes.expandOpen]: expanded
})}
onClick={() => handleExpandClick(index)}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMoreIcon />
</IconButton>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<CardContent>
<Typography paragraph>{data.gender}</Typography>
<Typography paragraph>{data.eye_color}</Typography>
<Typography paragraph>{data.height}</Typography>
</CardContent>
</Collapse>
</Card>
);
});
return <div className={classes.card_container}>{a}</div>;
};
export default MediaCard;
更新:
我分离了组件,只能显示每个字符的数据,但仍然无法将扩展功能隔离到特定卡。如果有帮助,我创建了一个代码框链接来查看我的代码。谢谢。
https://codesandbox.io/embed/determined-frog-p0k8w?fontsize=14
【问题讨论】:
-
你只有一个
expanded状态变量。如果您希望能够单独展开项目,则需要为每个项目设置一个单独的expanded值 -
@MoIsmat 感谢您的帮助。我仍然很难理解如何使用钩子映射单独的扩展状态。到目前为止,我取得的最大进展是只显示特定字符的数据。我创建了一个代码框来显示我的代码。也许这会有所帮助codesandbox.io/embed/determined-frog-p0k8w?fontsize=14
-
我认为你试图一次学习太多东西。我建议您首先尝试在不使用 Material-ui 的情况下执行此操作。只需使用带有按钮的 div 来扩展内容。使其成为可重复使用的组件,然后将其与您的所有项目一起使用。搞清楚 React 之后,你就可以转向学习类库,比如 material-ui
-
@MoIsmat 我想通了。问题是样式,因为我的代码是正确的(不确定结构是否正确,因为我仍在学习但功能性哈哈)。卡片所在的行仅增加了该行中所有卡片的高度,因此我控制了每张卡片的高度。对我来说,一个快速的解决方法是将卡片高度设置为 100%,它似乎可以工作。我确实做了一个没有 material-ui 扩展的操作,这确实帮助我看到了这个问题,所以感谢您的建议。如果您在我的代码中看到任何其他可能我做错或本可以做得更好的内容,请告诉我。我将在下面的另一个答案中附上这两个代码示例。
标签: reactjs material-ui react-hooks