Javascript 即使状态更改,页面刷新后也不会重新呈现组件

Javascript 即使状态更改,页面刷新后也不会重新呈现组件,javascript,reactjs,Javascript,Reactjs,我有个很奇怪的问题。我是说,对我来说,真的。这不是某种使用setState而不是这个.state的问题。我正在开发旅行计划应用程序。我正在使用ContextAPI,它为整个应用程序提供登录信息和记录的用户数据、用户行程等。 日程组件,显示每日行程日程是上下文订阅服务器。 现在我想删除其中一个trip days,同时订阅上下文是由Schedule列表上的Schedule组件呈现的组件。然后奇迹发生了: 当我在登录到应用程序后立即执行此操作时,一切正常。但当我刷新页面并在另一天删除时,上下文状态(如

我有个很奇怪的问题。我是说,对我来说,真的。这不是某种使用setState而不是这个.state的问题。我正在开发旅行计划应用程序。我正在使用ContextAPI,它为整个应用程序提供登录信息和记录的用户数据、用户行程等。 日程组件,显示每日行程日程是上下文订阅服务器。 现在我想删除其中一个trip days,同时订阅上下文是由Schedule列表上的Schedule组件呈现的组件。然后奇迹发生了:

当我在登录到应用程序后立即执行此操作时,一切正常。但当我刷新页面并在另一天删除时,上下文状态(如我所说)保存所有数据,包括通过开发人员工具检查的日程列表更改中的天数,但日程组件不会重新呈现自身,所以删除的元素仍然可见。 但正如我所说的,状态会发生变化,并且在删除操作之前没有页面刷新,一切都正常工作。另外,当我切换到另一个选项卡时,日程表只是其中一个选项卡,我在导航栏的“渲染成本和注释组件”上有“成本和注释”选项卡,然后返回到重新渲染的日程表选项卡,一切看起来都很好,组件根据上下文状态显示信息

代码是这样工作的:deletion context函数由Day.js context subscriber中的delete图标点击触发,Day.js也由Schedule.js context subscriber呈现

在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组件中,函数组件将接收props I控制台日志props.context.trip[0]。day[0]-第一天。它不是一个对象,只是纯文本,所以当我在控制台中单击它时,它不会被计算。 在删除它之前,控制台会记录第一项。在我删除它之后,控制台会记录第二个项目,所以现在它是列表中的第一个项目,所以给日程安排的道具会改变,但不会触发渲染。。。那到底是怎么回事

//更新2 我还注意到,当我从另一个组件切换到Schedule组件时,效果很好,例如我正在刷新/costs endpoint上的页面,然后单击导航栏菜单上的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;
-------上下文:

export default function withContext(Component) {
    return function ContextComponent(props) {
        return (
            <Context.Consumer>
                {context => <Component {...props} context={context} />}
            </Context.Consumer>
    );
    }
}


你改变了你的状态。 在这里,您可以在不使用setState的情况下更改状态中的对象:

newTrip.days = newTrip.days.filter(day => day.id !== id)

然后在map函数中,总是返回它已更新的相同对象。 因此,要解决您的问题,您可以尝试更改deleteDay方法:

更新: 计划组件中还有一个问题

您需要动态获取当前行程,不要在构造函数中设置:

试试这个:

constructor(props) {
    super(props);
    this.getTrip = this.getTrip.bind(this);
}
getTrip() {
    return this.props.context.userData.trips.find(trip => {
        return `${trip.id}`===this.props.match.params.id;
    });
}
render() {
    const trip = this.getTrip();

    return (
        ...
        <ul>
            {trip.days.map((day,index) => {
                return <DayWithContext 
                    inOverview={false} 
                    key={day.id} 
                    number={index} 
                    day={day} 
                    tripId={trip.id}    
                />
            })}
        </ul>
        ...
    )
}

感谢您的回答-我忘记了=没有复制数组。我通过使用:const trips=Array.fromthis.state.userData.trips修复了这个问题;让newTrip=trips.findtrip=>trip.id==tripId;但它仍然没有解决我的问题。上下文状态得到更新,但计划组件保持不变。当我登录后第一次看到应用程序时,它工作正常。但是,当我刷新页面会话时,我会保持登录状态,并对列表中的任何其他元素执行相同的操作,但什么也不会发生。法庭后面的状态发生了变化,但没有触发渲染…@hayanawama,你刚才展示的代码并没有解决数据突变的问题。如果您试图在代码之后更改newTrip变量,您还将更改您所在州的trip。尝试以下代码:const arr=[{foo:bar}];const newArr=Array.fromarr;newArr[0].foo=baz;console.logarr[0].foo;很抱歉设置了格式,注释不允许使用您看到的美丽格式,Array.from不创建新对象,它只是将链接复制到原始对象。你需要做的和我在回答中所说的完全一样,你需要为你的newTrip创建一个新对象。@hayanawama,也是我在你的Schedule.js中看到的潜在bug。您需要使用day.id作为组件的键:key={day.id}哦,所以我被一些带有Array.from的网站误导了。我已经完成了您所说的一切,还将UpdateRip中的第一行更改为const trips=[…this.state.userData.trips]。仍然不起作用。我也换了钥匙,顺便问一下,为什么?。如果您仍然愿意帮助,您可以查看我在主要问题底部的更新说明-问题在别处,因为状态已更改,组件将收到新道具,但不会重新渲染:/Thank man!!!!!!!!!!!现在很有魅力。使您的函数成为箭头式函数,但构造函数中没有绑定。谢谢你的时间,我从这次谈话中学到了很多。看见 ms like我必须阅读很多关于组件生命周期的文章,并做出总体反应。但是现在我不明白为什么它在没有页面刷新的情况下就可以工作,因为trip一直都是固定的:D还有一个问题,将函数放在里面会不会产生同样的效果?在Schedule.js中,您使用的是this.trip。你是怎么设定的?
constructor(props) {
    super(props);
    this.getTrip = this.getTrip.bind(this);
}
getTrip() {
    return this.props.context.userData.trips.find(trip => {
        return `${trip.id}`===this.props.match.params.id;
    });
}
render() {
    const trip = this.getTrip();

    return (
        ...
        <ul>
            {trip.days.map((day,index) => {
                return <DayWithContext 
                    inOverview={false} 
                    key={day.id} 
                    number={index} 
                    day={day} 
                    tripId={trip.id}    
                />
            })}
        </ul>
        ...
    )
}