在 WillMount() 中设置的状态在 DidMount() 中不可访问
Posted
技术标签:
【中文标题】在 WillMount() 中设置的状态在 DidMount() 中不可访问【英文标题】:State set in WillMount() not accessible in DidMount() 【发布时间】:2018-05-01 07:25:36 【问题描述】:我有一个组件需要 API 获取请求来检索 componentDidMount()
上的一些信息。该获取请求依赖于存储在状态中的信息,这些信息是我通过ComponentWillMount()
上调用的函数设置的。
我的willMount()
运行,然后我点击了我的render()
方法,但尚未设置状态,因此它点击didMount()
但由于数据尚未处于状态而失败。我哪里错了?
编辑:所有函数都绑定在构造函数中(未显示)
componentWillMount()
this.enforceEmployeeAuth();
this.loadEmployeeInfo();
componentDidMount()
this.fetchSurveyFields();
// Initial check to confirm if the user should be allowed to access any information.
enforceEmployeeAuth()
// Get request to confirm that the current user is of type EMPLOYEE
API.get("user/employee_auth", , (res) =>
// Employee Auth: True if employee, else false
this.setState(
employee_auth: res.employee_auth,
);
);
// Load up relevant information for currentUser/employee
loadEmployeeInfo()
API.get("client/currentEmployee", , function(res)
this.setState(
employee : res.employee,
employee_company : res.employee_company,
)
.bind(this));
fetchSurveyFields()
debugger
API.get('client/survey',
survey: this.state.employee_company.survey_name
, function(res)
debugger
)
render()
debugger
return (
<h2 className="text-charcoal text-left">Employee Rubric</h2>
)
【问题讨论】:
您需要等待 .get 的结果返回才能使用数据 当从 componentWillMount() 方法调用时,您是否检查过 loadEmployeeInfo() 方法中的数据是否正确设置了状态 我用调试器检查了流程。如下:willMount()
--> 运行函数.... render()
--> 没有状态更新... didMount()
--> 状态仍然没有改变,函数将失败.... @ 987654330@ --> 呈现第一个状态变化.... render()
--> 呈现第二个状态变化
@Cruiser 我认为你是对的,但是在我收到结果之前如何防止我的其他东西运行?
您的 API.get
返回一个在您的 componentDidMount
运行时尚未履行的承诺 - 这就是您的状态还没有数据的原因
【参考方案1】:
您应该保存两个 api 调用返回的承诺。然后在解决componentDidMount 中的问题时,您应该对fetchSurveyFields 进行api 调用。像这样
componentWillMount()
this.promises = [];
this.promises.push(this.enforceEmployeeAuth());
this.promises.push(this.loadEmployeeInfo());
componentDidMount()
Promise.all(this.promises)
.then(([resp1, resp2]) =>
//You can see here if you still wanna set state.
this.fetchSurveyFields();
);
// Initial check to confirm if the user should be allowed to access any information.
enforceEmployeeAuth()
// Get request to confirm that the current user is of type EMPLOYEE
API.get("user/employee_auth", , (res) =>
// Employee Auth: True if employee, else false
this.setState(
employee_auth: res.employee_auth,
);
);
// Load up relevant information for currentUser/employee
loadEmployeeInfo()
API.get("client/currentEmployee", , function(res)
this.setState(
employee : res.employee,
employee_company : res.employee_company,
)
.bind(this));
fetchSurveyFields()
debugger
API.get('client/survey',
survey: this.state.employee_company.survey_name
, function(res)
debugger
)
render()
debugger
return (
<h2 className="text-charcoal text-left">Employee Rubric</h2>
)
【讨论】:
【参考方案2】:您的函数依赖于异步请求,这意味着它们会在请求返回后使用请求的结果设置状态,如果这有意义的话。
在您的渲染方法中,检查您的状态是否有效,如果无效则返回 null。下次设置状态时将再次调用 render 方法(即当您的请求成功时,因为状态已在其回调中设置)。
【讨论】:
【参考方案3】:您如何将授权令牌作为道具从父组件传递,然后使用 componentWillReceiveProps 挂钩触发对 API 的请求?
【讨论】:
以上是关于在 WillMount() 中设置的状态在 DidMount() 中不可访问的主要内容,如果未能解决你的问题,请参考以下文章
如何根据文本字段 Material UI 中设置的值将对象设置为状态
React - 访问在 useEffect 挂钩中设置的对象属性
在 WebSocketServlet (Jetty WebSockets) 中访问在 HttpServlet 中设置的会话属性