我正在尝试使用React使用JS编写一个初级项目(什么都不做,只是为了获得一些经验)。因此-我有点新鲜...我要去那个通用的“ notes app”。
但是从服务器获取便笺并渲染它们(使用@ material-ui Card元素)面临一个问题:所有便笺处于共享状态:单击某人的“展开”图标会使所有卡片展开(但仅显示数据在一个点击)。再次单击(在之前单击的那一项上)将全部关闭
这是我第一次使用'useState'钩子和@ material-ui。 我有一些关于React的经验,包括类和无状态组件。但是以前没有遇到过。
这是Notes组件,它呈现与保存的一样多的Note元素。
parseNotes = (data) => {
const toBeNotes = [];
for (let key in data) {
toBeNotes.push(data[key]);
}
const aux = toBeNotes.map((note, i) => {
return (
<Note key={i} {...note} />
)
})
this.setState({ notes: aux });
}
render() {
return (
<div className="notes">{...this.state.notes}</div>
)
}
这是Note组件的代码:
const [open, setOpen] = useState(false);
function openHandler() {
setOpen(!open);
}
return (
<Card raised className="note">
<CardHeader
title={props.title}
subheader={`Due at: ${props.date}, at ${props.time}`}
/>
<CardActions>
<IconButton>
<ExpandMoreIcon
onClick={openHandler}
/>
</IconButton>
</CardActions>
<Collapse in={open}>
<CardContent>
<h6>{props.body}</h6>
</CardContent>
</Collapse>
</Card>
)
任何帮助将不胜感激!
答案 0 :(得分:0)
如果将Note
更改为以下内容,会发生什么情况:
export const Note = ({date, time, title, body}) => {
const [open, setOpen] = useState(false);
return (
<Card raised className="note">
<CardHeader
title={title}
subheader={`Due at: ${date}, at ${time}`}
/>
<CardActions>
<IconButton>
<ExpandMoreIcon
onClick={() => setOpen(!open)}
/>
</IconButton>
</CardActions>
<Collapse in={open}>
<CardContent>
<h6>{body}</h6>
</CardContent>
</Collapse>
</Card>
)
};
(侧边栏:您可以将open
传递到ExpandMoreIcon
中,以便可以更改图标以反映所反映的动作)
在这种情况下,open
应该只与您正在使用的Card
相关,并且不会/不应该影响显示屏中的其他Note
。如果您一次需要处理一个打开/关闭操作,则必须从一个较高的组件向下传递一种方法,该方法可以跟踪每个组件的打开/关闭状态(可能基于其索引)(哪个,BTW,您永远不要使用作为您的key
。只需为每个Note
提供自己的唯一标识符,然后将其用作您的key
。)
答案 1 :(得分:0)
每个组件都独立于另一个组件工作。因此2个音符的“打开”状态是不同的,并且仅在内部绑定到它们的音符。因此,它不会影响其他注释。错误原因必须不同。您必须提供这2个文件的完整代码。
为确认起见,我编写了一段代码,其中制作了一个最初显示红色的ColoredButton组件,当我单击它时,它切换为黑色,再次单击时,它切换为红色,因此然后,在我的App Component(直接在index.js中呈现)中使用此组件10次,并注意到每个ColoredComponent的行为都独立于另一个组件。
ColorButton.js
const ColoredButton = props => {
const redHex = "#f00";
const blackHex = "#000";
const [color, setColor] = useState(redHex);
return (
<React.Fragment>
<button
onClick={event => {
event.preventDefault();
if (color === redHex) {
setColor(blackHex);
} else {
setColor(redHex);
}
}}
style={{ color: `${color}` }}
>
Toggle My Color
</button>
</React.Fragment>
);
};
export default ColoredButton;
index.js
import React from "react";
import ReactDOM from "react-dom";
import ColoredButton from "./ColoredButton";
import "./styles.css";
function App() {
let buttons10 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
return (
<React.Fragment>
{buttons10.map(buttonNo => (
<ColoredButton key={buttonNo} />
))}
</React.Fragment>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
您可以在CodeSandbox上尝试使用此代码。
如果此示例代码不能帮助您解决问题,请提供这两个文件的完整代码。