Reactjs 上下文提供程序未触发重新呈现this.props.children

Reactjs 上下文提供程序未触发重新呈现this.props.children,reactjs,Reactjs,我使用上下文提供程序(AccountProvider.js)作为一种向其所有子组件提供帐户详细信息(以及通过socket.io连接提供通知)的方法。通知和用户对象会很好地加载到AccountProvider组件中,并且实际上会不断更新自己的状态 知道如果父组件的状态发生更改,这应该意味着父组件的子组件都应该重新渲染,对吗?显然,这里的情况并非如此,我似乎不明白为什么 这个问题有什么解决办法吗?可能需要强制更新子组件 AccountProvider.js import React, { Compo

我使用上下文提供程序(AccountProvider.js)作为一种向其所有子组件提供帐户详细信息(以及通过socket.io连接提供通知)的方法。通知和用户对象会很好地加载到AccountProvider组件中,并且实际上会不断更新自己的状态


知道如果父组件的状态发生更改,这应该意味着父组件的子组件都应该重新渲染,对吗?显然,这里的情况并非如此,我似乎不明白为什么

这个问题有什么解决办法吗?可能需要强制更新子组件

AccountProvider.js

import React, { Component } from 'react'
import axios from 'axios'
import socketIOClient from "socket.io-client";
import config from '../config/config'

export const myContext = React.createContext();

export default class AccountProvider extends Component {

    state = {
        data: []
    }

    async componentDidMount() {
        const auth_token = localStorage.getItem('jwt token')
        const header = 'Bearer ' + auth_token;
        const res = await axios.get(config.API_URL+'/api/account', {headers: {Authorization:header}});
        const blob = await axios.get(config.API_URL+'/' + res.data.image, {headers: {Authorization:header}, responseType: "blob"});
        var user = res.data;
        user["image"] = URL.createObjectURL(blob.data);

        this.setState({
            data: {user}
        });

        const io = socketIOClient(config.REDIS_URL, { query: {jwt: localStorage.getItem('jwt token')} });

        io.on("event", data => {
            if (data !== this.state.notifications){
                var curr_data = this.state.data;
                curr_data["notifications"] = data;
                this.setState({data: curr_data});
            }
        });

        io.on("reconnect", () => {
            io.emit("jwt", localStorage.getItem('jwt token'));
        })
    }


    render() {
        return (
            <myContext.Provider value={this.state.data}>
                {this.props.children}
            </myContext.Provider>
        )
    }
}
import React, { Component } from 'react'
import AccountContent from './AccountContent';
import PendingCard from '../PendingCard';
import {myContext} from '../../../AccountProvider'

class Dashboard extends Component {
    render() {
        // The following should log notifications after AccountProvider rerenders
        console.log(this.context.notifications && this.context.notifications);
        return (
            <>
                { this.props.hasCard ? <AccountContent/> : <PendingCard/> }
            </>
        )
    }
}

Dashboard.contextType = myContext;
export default Dashboard;
import React,{Component}来自“React”
从“axios”导入axios
从“socket.io客户端”导入socketIOClient;
从“../config/config”导入配置
export const myContext=React.createContext();
导出默认类AccountProvider扩展组件{
状态={
数据:[]
}
异步组件didmount(){
const auth_token=localStorage.getItem('jwt token')
const header='Bearer'+身份验证令牌;
const res=await axios.get(config.API_URL+'/API/account',{headers:{Authorization:header}});
const blob=await axios.get(config.API_URL+'/'+res.data.image,{headers:{Authorization:header},responseType:“blob”});
var user=res.data;
用户[“image”]=URL.createObjectURL(blob.data);
这是我的国家({
数据:{user}
});
const io=socketIOClient(config.REDIS_URL,{query:{jwt:localStorage.getItem('jwt token')});
io.on(“事件”,数据=>{
if(数据!==this.state.notifications){
var curr_data=this.state.data;
当前数据[“通知”]=数据;
this.setState({data:curr_data});
}
});
io.on(“重新连接”,()=>{
io.emit(“jwt”,localStorage.getItem(“jwt令牌”);
})
}
render(){
返回(
{this.props.children}
)
}
}
App.js(渲染)


(
*/}
)}/>
Dashboard.js

import React, { Component } from 'react'
import axios from 'axios'
import socketIOClient from "socket.io-client";
import config from '../config/config'

export const myContext = React.createContext();

export default class AccountProvider extends Component {

    state = {
        data: []
    }

    async componentDidMount() {
        const auth_token = localStorage.getItem('jwt token')
        const header = 'Bearer ' + auth_token;
        const res = await axios.get(config.API_URL+'/api/account', {headers: {Authorization:header}});
        const blob = await axios.get(config.API_URL+'/' + res.data.image, {headers: {Authorization:header}, responseType: "blob"});
        var user = res.data;
        user["image"] = URL.createObjectURL(blob.data);

        this.setState({
            data: {user}
        });

        const io = socketIOClient(config.REDIS_URL, { query: {jwt: localStorage.getItem('jwt token')} });

        io.on("event", data => {
            if (data !== this.state.notifications){
                var curr_data = this.state.data;
                curr_data["notifications"] = data;
                this.setState({data: curr_data});
            }
        });

        io.on("reconnect", () => {
            io.emit("jwt", localStorage.getItem('jwt token'));
        })
    }


    render() {
        return (
            <myContext.Provider value={this.state.data}>
                {this.props.children}
            </myContext.Provider>
        )
    }
}
import React, { Component } from 'react'
import AccountContent from './AccountContent';
import PendingCard from '../PendingCard';
import {myContext} from '../../../AccountProvider'

class Dashboard extends Component {
    render() {
        // The following should log notifications after AccountProvider rerenders
        console.log(this.context.notifications && this.context.notifications);
        return (
            <>
                { this.props.hasCard ? <AccountContent/> : <PendingCard/> }
            </>
        )
    }
}

Dashboard.contextType = myContext;
export default Dashboard;
import React,{Component}来自“React”
从“./AccountContent”导入AccountContent;
从“../PendingCard”导入PendingCard;
从“../../../AccountProvider”导入{myContext}
类仪表板扩展组件{
render(){
//在AccountProvider重新提交后,应记录以下通知
log(this.context.notifications&&this.context.notifications);
返回(
{this.props.hasCard?:}
)
}
}
Dashboard.contextType=myContext;
导出默认仪表板;
更改:

var curr_data = this.state.data;
curr_data["notifications"] = data;
this.setState({data: curr_data});
与:


您并没有真正用第一个案例更新状态

“这意味着父组件的子组件也应该重新呈现,对吗?”没有。这可能是重复的,我很好奇为什么第一个案例没有更新状态!它不起作用,因为您获取当前数据,然后更改它。。。但是curr_数据和数据是同一个对象。。。所以当你设置状态“数据”时。。。因此没有新的渲染