我正在尝试做的事情
我有一个带有“配置文件”数组的主要组件。对于每个配置文件,我有两个不同的条件组件(一次只显示一个)。这两个组件中的每一个都有一个按钮,单击该按钮可以切换组件。所以我将状态提升到主组件,使用“useState”钩子创建组件状态(这是一个数组,其中每个索引都是一个字符串,表示要为配置文件数组中的每个元素显示的子组件),我为这些点击创建了两个事件处理函数,并将它们作为渲染道具传递给它们的子组件。
它们从第一个子组件开始。
问题以及我是如何找到它的
当您按下按钮切换到另一个组件时,它会起作用。当您按下按钮返回时,它会崩溃。说“TypeError:无法分配给字符串'大'的只读属性'0'”。我在 useState 初始化之后以及每个函数中的状态更改调用之后放置了一些 console.log(state) 。会发生什么(只有一个元素的测试列表)是
- 组件初始化时,状态显示为['normal'](原始状态,良好)
- 单击第一个组件的按钮时,['normal'] 变为 ['large'](如预期的那样)
- 现在重新渲染组件时,状态变为“大”(不再是数组)
- 单击第二个组件的按钮时,应用程序崩溃导致它无法更改数组元素,因为它不再是数组
主要部件
const Peers = props => {
let dummyPeer = {
_id: "9asdf98sj3942j4fs9ji",
user: {
name: "Test Peer",
avatar: "//www.gravatar.com/avatar/cd56136f6d9abfdf4a0198dc9ce656c8?s=200&r=pg&d=mm"
},
bio: "Biography for Test Peer",
year: "2022",
courses: [
"CISC124",
"PSYC223",
"PSYC236",
"COMM200",
"CISC251"
]
}
let profiles = [];
profiles.push(dummyPeer);
let initialState = [];
profiles.forEach(profile => {
initialState.push("normal");
});
let [viewState, setViewState] = useState(initialState);
console.log(viewState);
const openLargeView = (id) => {
let changeIndex = profiles.map(profile => profile._id).indexOf(id);
setViewState(state => state[changeIndex] = "large");
console.log(viewState);
}
const closeLargeView = (id) => {
let changeIndex = profiles.map(profile => profile._id).indexOf(id);
setViewState(state => state[changeIndex] = "normal");
console.log(viewState);
}
return (
<Fragment>
{profiles.map((profile, index) => (<Fragment key={profile._id} >
{viewState[index] === "normal" ? (
<Peer openLargeView={openLargeView} profile={profile} />
) : (
<ViewPeer closeLargeView={closeLargeView} profile={profile} />
)}
</Fragment>))}
</Fragment>
)
}
子组件 1:
const Peer = ({ profile, openLargeView }) => {
const { _id, user, bio, year, courses } = profile;
const { avatar } = user;
return (<Fragment>
<div className="card-row">
<div className="profile-header">
<h1 className="peer-text row-title"> {user.name} </h1>
<p className="peer-text peer-small"> {year} </p>
<img className="avatar avatar-peer-small" src={avatar} alt='' />
</div>
<button onClick={() => openLargeView(_id)} className="btn-small"> More </button>
</div>
</Fragment>)
}
子组件 2:
const ViewPeer = ({ profile, closeLargeView }) => {
const { _id, user, bio, year, courses } = profile;
const { avatar } = user;
let courseElements = courses.map((course, index) =>
<li key={index} className="profile-text"> {course} </li>
);
return (
<Fragment>
<div className="card-md peer-card">
<div className="profile-header">
<h1 className="peer-text"> {user.name} </h1>
<img className="avatar avatar-peer" src={avatar} alt='' />
</div>
<div className="profile-info">
<h2 className="profile-text"> {bio} </h2>
<h2 className="profile-text2"> Year: {year} </h2>
<ul className="course-list"> {courseElements} </ul>
<div className="profile-button-group">
<button onClick={() => closeLargeView(_id)} className="btn-small"> Close </button>
<button className="btn-small"> Send Buddy Request </button>
</div>
</div>
</div>
</Fragment>
)
}
预期和实际结果
我希望它在单击第一个组件的按钮时返回到原始组件,但状态变成了一个字符串数组并且应用程序崩溃了。