我正在使用上下文提供程序(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>
)
}
}
App.js(呈现)
<AccountProvider>
<Route
path="/dashboard"
render={({ match: { url } }) => (
<Dashboard>
<Switch>
<Route path={`${url}/Account`} component={Account} exact />
<Route path={`${url}/Deposits`} component={Deposits} exact />
<Route path={`${url}/Notifications`} component={Client} exact />
<Route path={`${url}/`} component={Account} exact /> */}
<Route component={Page404Dashboard} />
</Switch>
</Dashboard>
)}/>
</AccountProvider>
Dashboard.js
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;
答案 0 :(得分:2)
更改:
var curr_data = this.state.data;
curr_data["notifications"] = data;
this.setState({data: curr_data});
具有:
var curr_data = Object.assign({}, this.state.data);
curr_data["notifications"] = data;
this.setState({data: curr_data});
您并没有真正用第一种情况更新状态