无法在现有状态转换期间更新 [英] Cannot update during an existing state transition
问题描述
当我加载时,我的流星项目一直使我的浏览器崩溃.如果我在 App.jsx 文件中注释掉 this.setState({input_36:currentApp.input_36});
,我只能避免浏览器崩溃.有人可以告诉我如何修复我的代码,以便项目可以加载而不会崩溃,如果您单击
中的任何超链接,它会重新呈现表单吗?并通过确保 href=
属性来确保链接符合 WCAG 和搜索引擎优化?
这是我的项目...在终端命令行中我做
meteor 创建 crudappcd crudapprm crudapp.js流星删除自动发布流星添加反应流星加铁:路由器
然后我的项目中有以下文件
crudapp.html
<title>申请表</title>头部><身体><div id="render-target"></div>
crudapp.jsx
Applications = new Mongo.Collection("applications");如果(流星.isServer){Meteor.publish("应用程序", function(){返回 Applications.find();});}var configAppRoute = {waitOn:function(){return [Meteor.subscribe('applications')]},action:applicationController};Router.route('/application',configAppRoute);Router.route('/application/:appid',configAppRoute);函数应用控制器(){var 路由器 = 这个;流星.启动(函数(){ReactDOM.render(<App router={router}/>, document.getElementById("render-target"));});}流星.方法({保存应用程序(formVals){formVals['createdAt'] = new Date();Applications.insert(formVals);}});
App.jsx
App = React.createClass({混合:[ReactMeteorData],getMeteorData() {返回 {应用程序:Applications.find({}, {sort: {createdAt: -1}}).fetch(),}},getInitialState:函数(){返回 this.loadForm(this.props.router.params.appid);},加载表单(应用程序 ID){var currentApp = Applications.findOne({_id:appId});if(!currentApp) currentApp = {};返回当前应用程序;},clickLoadForm(appId){var currentApp = this.loadForm(appId);//this.setState({input_36:currentApp.input_36});},渲染列表应用程序(){var _this = this;返回 this.data.applications.map(function(applicationform,i) {return <li key={"li"+i}><a onClick={_this.clickLoadForm(applicationform._id)} href={Meteor.absoluteUrl()+'application/' +applicationform._id} key={"a"+i}>版本{applicationform._id}</a></li>;});},处理提交(事件){event.preventDefault();var refs = this.refs;var formVals = new Object();Object.keys(refs).map(function(prop, index){if(refs[prop].nodeName.match(/(INPUT|SELECT|TEXTAREA)/).length > 0)formVals[prop] = refs[prop].value;});Meteor.call("saveApplication", formVals);},handleChange:函数(e){this.setState({ input_36: e.target.value });},使成为() {返回 (<div className="容器">
- {this.renderListApplications()}
<form className="new-task" onSubmit={this.handleSubmit} ><input ref="input_36" type="text" tabIndex="1" value={this.state.input_36} onChange={this.handleChange}/>
);}});
然后我进入命令行并输入 meteor
来启动项目.然后我去我的网络浏览器.将出现一个文本字段,以便您可以输入内容并按几次 Enter,系统会自动显示您创建的每个表单的列表.
接下来我通过取消对粗线的注释来修改 App.jsx.项目将重新编译.然后我转到我的 Web 浏览器,它因为无限循环而死机,并显示错误消息
<块引用>无法在现有状态转换期间更新(例如在渲染"中).Render 方法应该是 props 和 state 的纯函数.
如何解决这种情况,以便加载项目并单击链接重新呈现表单?
John 说:改变onClick={_this.clickLoadForm(applicationform._id)}
到 onClick={_this.clickLoadForm.bind(_this,applicationform._id)}
如果这不起作用,那么也许下面的一些变体
<小时>尝试将 _this.clickLoadForm(_this.props.router.params.appid)
更改为 _this.clickLoadForm
版本 {applicationform._id}</a>clickLoadForm(e) {var appId = e.target.dataset.value;var currentApp = this.loadForm(appId);this.setState({input_36:currentApp.input_36});}
似乎您已经在执行 clickLoadForm
函数从而触发 this.setState
My meteor project keeps crashing my browser when I load it up. I can only avoid browser crash if I comment out this.setState({input_36:currentApp.input_36});
in the App.jsx file. Can someone tell me how to fix my code so that the project can load without crashing and if you click on any hyper links in the <ul>
, it will re-render the form? And make sure the links are WCAG compliant and search engine optimized by ensuring the href=
attribute is there?
Here's my project...in terminal command line I do
meteor create crudapp
cd crudapp
rm crudapp.js
meteor remove autopublish
meteor add react
meteor add iron:router
Then I have the following files in my project
crudapp.html
<head>
<title>Application Form</title>
</head>
<body>
<div id="render-target"></div>
</body>
crudapp.jsx
Applications = new Mongo.Collection("applications");
if(Meteor.isServer)
{
Meteor.publish("applications", function(){
return Applications.find();
});
}
var configAppRoute = {waitOn:function(){return [Meteor.subscribe('applications')]},action:applicationController};
Router.route('/application',configAppRoute);
Router.route('/application/:appid',configAppRoute);
function applicationController()
{
var router = this;
Meteor.startup(function () {
ReactDOM.render(<App router={router} />, document.getElementById("render-target"));
});
}
Meteor.methods({
saveApplication(formVals) {
formVals['createdAt'] = new Date();
Applications.insert(formVals);
}
});
App.jsx
App = React.createClass({ mixins: [ReactMeteorData], getMeteorData() { return { applications: Applications.find({}, {sort: {createdAt: -1}}).fetch(), } }, getInitialState: function() { return this.loadForm(this.props.router.params.appid); }, loadForm(appId) { var currentApp = Applications.findOne({_id:appId}); if(!currentApp) currentApp = {}; return currentApp; }, clickLoadForm(appId) { var currentApp = this.loadForm(appId); //this.setState({input_36:currentApp.input_36}); }, renderListApplications() { var _this = this; return this.data.applications.map(function(applicationform,i) { return <li key={"li"+i}><a onClick={_this.clickLoadForm(applicationform._id)} href={Meteor.absoluteUrl()+'application/' +applicationform._id} key={"a"+i}>Version {applicationform._id}</a></li>; }); }, handleSubmit(event) { event.preventDefault(); var refs = this.refs; var formVals = new Object(); Object.keys(refs).map(function(prop, index){ if(refs[prop].nodeName.match(/(INPUT|SELECT|TEXTAREA)/).length > 0) formVals[prop] = refs[prop].value; }); Meteor.call("saveApplication", formVals); }, handleChange: function(e) { this.setState({ input_36: e.target.value }); }, render() { return ( <div className="container"> <ul> {this.renderListApplications()} </ul> <div>{JSON.stringify(this.data.currentApplication)}</div> <form className="new-task" onSubmit={this.handleSubmit} > <input ref="input_36" type="text" tabIndex="1" value={this.state.input_36} onChange={this.handleChange} /> <button type="submit">Submit</button> </form> </div> ); } });
Then I go to command line and type meteor
to start up the project. Then I go to my web browser. A text field appears so you can type something and press enter a few times, and a list to each form you created will automatically appear.
Next I modify App.jsx by uncommenting the bold line. The project will recompile. Then I go to my web browser and it freezes because of the infinite loop with the error message
Cannot update during an existing state transition (such as within "render"). Render methods should be a pure function of props and state.
How do I fix this situation so that it will load up the project and click on links will re-render the form?
John says:
Change
onClick={_this.clickLoadForm(applicationform._id)}
to onClick={_this.clickLoadForm.bind(_this,applicationform._id)}
If that doesn't work, then maybe some variation of the below
Try changing _this.clickLoadForm(_this.props.router.params.appid)
to _this.clickLoadForm
<a onClick={_this.clickLoadForm}
data-value={_this.props.router.params.appid}
href={Meteor.absoluteUrl()+'application/' +applicationform._id}
key={"a"+i}>
Version {applicationform._id}
</a>
clickLoadForm(e) {
var appId = e.target.dataset.value;
var currentApp = this.loadForm(appId);
this.setState({input_36:currentApp.input_36});
}
It seems like you're already executing the clickLoadForm
function thus triggering this.setState
这篇关于无法在现有状态转换期间更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!