【发布时间】:2019-08-31 13:04:58
【问题描述】:
我遇到了非常奇怪的问题。我的意思是,对我来说,真的。这不是某种“使用 setState 而不是 this.state”的问题。我正在开发旅行计划应用程序。我正在使用 ContextAPI,它为整个应用程序提供登录信息和用户数据(记录的用户行程等)。 “日程”组件,显示每天的行程日程是上下文订阅者。 现在我想删除其中一个行程日(Day,也订阅上下文是由 Schedule 组件在 Schedule 列表中呈现的组件)。然后神奇的事情发生了:
当我在登录应用程序后立即执行此操作时,一切正常。但是当我刷新页面并删除另一天时,上下文状态(正如我所说,它包含所有数据,包括日程表中的天数)更改(通过开发人员工具检查)但日程安排组件不会重新渲染本身,所以删除的元素仍然可见。 但正如我所说,状态发生变化,并且在删除操作之前没有页面刷新,一切正常。此外,当我切换到另一个选项卡时(计划只是其中一个选项卡,例如导航栏渲染成本和注释组件上的成本和注释选项卡),然后返回重新渲染的计划选项卡和所有内容看起来不错,组件根据上下文状态显示信息。
代码是这样工作的:删除(上下文函数)由 Day.js(上下文订阅者)中的删除图标点击触发,Day.js 由 Schedule.js(上下文订阅者也是)呈现。
在 Context.js 中
... context functions ...
//WRAPPER FOR DELETE FUNCTIONS
delete(url, deleteFunc) {
this.requestsApi.request(url, "DELETE", null)
.then(response => {
if(response.status===204) {
deleteFunc();
} else {
this.toggleRequestError(true);
}
})
.catch( err => {
console.log(err);
this.toggleRequestError(true);
});
}
deleteDay = (id, tripId) => {
let newTrip = this.state.userData.trips.find((trip => trip.id ===
tripId));
newTrip.days = newTrip.days.filter(day => day.id !== id)
this.updateTrip(newTrip);
}
updateTrip = (newTrip) => {
let trips = this.state.userData.trips;
this.setState(prevState => ({
userData : {
...prevState.userData,
trips: trips.map(trip => {
if(trip.id !== newTrip.id)
return trip;
else
return newTrip;
})
}
}
));
}
...
在 Schedule.js 中
... in render's return ...
<ul>
{this.trip.days.map((day,index) => {
return <DayWithContext
inOverview={false}
key={index}
number={index}
day={day}
tripId={this.trip.id}
/>
})}
</ul>
....
在 Day.js 中(删除图标)
...
<img
src={Delete}
alt="Delete icon"
className="mr-2"
style={this.icon}
onClick={() => {
this.props.context.delete(
`/days/${this.props.day.id}`,
() => this.props.context.deleteDay(this.props.day.id,
this.props.tripId)
);
}}
/>
...
任何人都知道发生了什么以及为什么在页面刷新后删除完成后无法重新呈现计划?即使上下文状态发生变化?我现在唯一的想法是这是某种错误......
//更新 在 Schedule 组件中,在函数 componentWillReceiveProps() 我控制台日志 props.context.trip[0].day[0] - 第一天。它不是对象,只是纯文本,因此“当我在控制台中单击它时”不会对其进行评估。 在我删除它之前,控制台会记录第一项。在我删除它之后,控制台会记录第二个项目(所以现在它是列表中的第一个项目),所以提供给 Schedule 的道具正在改变,但没有触发渲染......那里到底发生了什么?
//更新 2 我还注意到,当我从另一个组件切换到 Schedule 组件时,它运行良好(例如,我正在刷新 /costs 端点上的页面,然后单击导航栏菜单上的 Schedule 选项卡,这会导致 /schedule)。但是当我在 /schedule 端点上刷新页面时,会发生此“错误”并且组件不会重新呈现。
//从上下文渲染:
...
render() {
const {
isLoggedIn,
wasLoginChecked,
userData,
isLogoutSuccesfulActive,
isLogoutUnSuccesfulActive,
isDataErrorActive,
isRequestErrorActive,
isDataLoaded
} = this.state;
const context = {
isLoggedIn,
wasLoginChecked,
isLogoutSuccesfulActive,
isLogoutUnSuccesfulActive,
isDataErrorActive,
isRequestErrorActive,
userData,
isDataLoaded,
requestsApi : this.requestsApi,
toggleLogin : this.toggleLogin,
checkLogin: this.checkLogin,
setUserData: this.setUserData,
loadData: this.loadData,
addTrip: this.addTrip,
delete: this.delete,
deleteDay: this.deleteDay,
deleteActivity: this.deleteActivity,
deleteTrip: this.deleteTrip,
updateTrip: this.updateTrip,
uncheckLogin: this.uncheckLogin,
toggleLogoutSuccesful: this.toggleLogoutSuccesful,
toggleLogoutUnSuccesful: this.toggleLogoutUnSuccesful,
toggleRequestError: this.toggleRequestError,
toggleDataError: this.toggleDataError
};
return (
<Context.Provider value={context}>
{this.props.children}
</Context.Provider>
)
}
}
export const Consumer = Context.Consumer;
-------------上下文HOC:
export default function withContext(Component) {
return function ContextComponent(props) {
return (
<Context.Consumer>
{context => <Component {...props} context={context} />}
</Context.Consumer>
);
}
}
【问题讨论】:
-
在
Schedule.js中您使用的是this.trip。你是怎么设置的?
标签: javascript reactjs