我得到了错误
警告:设置状态(…):无法在现有状态转换期间更新(例如在render
或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数的副作用是一种反模式,但可以移动到componentWillMount
。
我发现原因是
const mapStateToProps = (state) => {
return {
notifications: state.get("notifications").get("notifications").toJS()
}
}
如果我不返回通知那里工作。但这是为什么呢?
import {connect} from "react-redux"
import {removeNotification, deactivateNotification} from "./actions"
import Notifications from "./Notifications.jsx"
const mapStateToProps = (state) => {
return {
notifications: state.get("notifications").get("notifications").toJS()
}
}
const mapDispatchToProps = (dispatch) => {
return {
closeNotification: (notification) => {
dispatch(deactivateNotification(notification.id))
setTimeout(() => dispatch(removeNotification(notification.id)), 2000)
}
}
}
const NotificationsBotBot = connect(mapStateToProps, mapDispatchToProps)(Notifications)
export default NotificationsBotBot
import React from "react"
class Notifications extends React.Component {
render() {
return (
<div></div>
)
}
}
export default Notifications
更新
在进一步调试时,我发现,以上可能不是根本原因,毕竟,我可以保留通知,但我需要删除调度(推送(/域))
我的重定向。
我是这样登录的:
export function doLogin (username, password) {
return function (dispatch) {
dispatch(loginRequest())
console.log("Simulated login with", username, password)
setTimeout(() => {
dispatch(loginSuccess(`PLACEHOLDER_TOKEN${Date.now()}`))
dispatch(addNotification({
children: "Successfully logged in",
type: "accept",
timeout: 2000,
action: "Ok"
}))
dispatch(push("/domains"))
}, 1000)
}
}
我发现是调度引起了警告,但为什么?“我的域”页面当前没有太多内容:
import {connect} from "react-redux"
import DomainsIndex from "./DomainsIndex.jsx"
export default connect()(DomainsIndex)
域索引
export default class DomainsIndex extends React.Component {
render() {
return (
<div>
<h1>Domains</h1>
</div>
)
}
}
更新2
我的pp.jsx。
<Provider store={store}>
<ConnectedRouter history={history}>
<Layout>
<Panel>
<Switch>
<Route path="/auth" />
<Route component={TopBar} />
</Switch>
<Switch>
<Route exact path="/" component={Index} />
<Route path="/auth/login" component={LoginBotBot} />
<AuthenticatedRoute exact path="/domains" component={DomainsPage} />
<AuthenticatedRoute exact path="/domain/:id" component={DomainPage} />
<Route component={Http404} />
</Switch>
<Notifications />
</Panel>
</Layout>
</ConnectedRouter>
</Provider>
发生这种情况的原因是当您调用doLogin
时,如果您从构造函数
中调用它。如果是这种情况,请尝试将其移动到组件WillMount
,尽管您应该从按钮调用此方法或在登录表单中输入命中。
如果这不是问题的根源,那么构造函数中已经记录了这一点。您可以在doLogin中对每一行进行注释,以准确知道哪一行给出了状态问题,我猜可能是推送或添加通知
我以前遇到过这个问题,并使用redux批处理操作解决了它。
这对于像你这样的用例非常有用,当你一次分派多个操作,并且你不确定更新何时会被触发,这样,多个操作只有一个分派。在你的例子中,似乎后续的addNotify
很好,但是第三个太多了,可能是因为它与历史api交互。
我会尝试做这样的事情(假设你的setTimeout当然会被一个api调用所取代):
import { batchActions } from 'redux-batched-actions'
export function doLogin (username, password) {
return function (dispatch) {
dispatch(loginRequest())
console.log("Simulated login with", username, password)
setTimeout(() => {
dispatch(batchActions([
loginSuccess(`PLACEHOLDER_TOKEN${Date.now()}`),
addNotification({
children: "Successfully logged in",
type: "accept",
timeout: 2000,
action: "Ok"
}),
push("/domains")
]))
}, 1000)
}
}
请注意,您必须下载该软件包,并在商店创建过程中启用批处理。
您的分派(推送('/Domain'))
还附带了其他分派,这些分派设置了在推送
生效后重新加载/卸载的连接组件(大概是关心通知的组件)的状态。
作为一种解决方法和概念证明,请尝试使用嵌套的零秒setTimeout
延迟分派(push('/domains'))
调用。这应该在任何其他操作完成后执行推送
(如渲染):
setTimeout(() => dispatch(push('/domains')), 0)
如果这行得通,那么您可能需要重新考虑您的组件结构。我认为通知是一个组件,您希望挂载一次,并在应用程序的生命周期内保持它。通过将其放在组件树的较高位置,并使其成为PureComponent
(这里是文档)来避免重新加载它。此外,如果应用程序的复杂性增加,您应该考虑使用库来处理异步功能,如redux-saga。
即使此警告通常由于错误的操作调用而出现(例如,在呈现时调用操作:onClick={action()}
而不是作为lambda传递:onClick={()=
在进一步的调试中,我发现,以上可能不是根本原因,毕竟,我可以保留通知,但我需要删除我的重定向。
我正在开发一个简单的待办事项列表反应应用程序(新的React.js)。我已经将项目添加到工作列表中,但删除项目会引起一个问题。在我的父反应组件中,我有以下代码: 我的组件: 运行此代码将带来: 警告:setState(...):无法在现有状态转换期间更新 问题: 为什么的渲染在添加项时立即执行回调,即: 但是,添加以删除Callback ie。
问题内容: 我正在尝试从渲染视图重构以下代码: 到绑定位于构造函数内的版本。原因是渲染视图中的绑定会给我带来性能问题,尤其是在低端手机上。 我创建了以下代码,但是我不断收到以下错误(很多错误)。该应用似乎陷入了循环: 以下是我使用的代码: 问题答案: 看起来您不小心在render方法中调用了该方法,而您可能想这样做。 如果您不想在onClick处理程序中创建lambda,我认为您将需要两个绑定方法
我正在重写一些旧的ReactJS代码,但在修复此错误时遇到了麻烦(此错误在控制台中重复大约1700次,DOM根本不呈现): 警告:设置状态(…):无法在现有状态转换期间更新(例如在或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数的副作用是一种反模式,但可以移动到。 我是一个组件,它将它的状态传递给一个应该呈现一些控件的组件。基于单击的控件,状态应该更改,并且应该呈现新的控件。
无法在现有状态转换期间更新(例如在“呈现”中)。呈现方法应该是道具和状态的纯函数。 我如何修复这种情况,使它将加载项目,并单击链接将重新呈现表单?