如何在不启动太多调用的情况下插入 reduxForm 组件
How can I insert a reduxForm component without starting too many calls
我总体上使用的是 MERN 堆栈,但我认为这个问题仅适用于 React 和 redux 形式。
每当我在我的用户仪表板中包含一个表单来添加一个项目时,我最终得到
Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
首先,我根本没有显式调用 componentWillUpdate 或 componentDidUpdate,所以我很难找到问题所在。如果我停止开发服务器,比如 CTRL+C
它有时会为我呈现(现在无法使用的)表单。
我试过了(都失败了):
- 只包含没有处理程序的表单
- 包含表格并在仪表板上处理
- 包含表格并在表格上处理
- 基于此 somewhat similar problem
删除对 bind(this)
的所有调用
我有类似的 redux-forms(在它们的容器中处理),可以很好地用于注册和登录
UserDashboard.js 当我添加表单时发生错误并且没有它时工作正常
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import * as actions from '../../actions';
import Cupcakes from './cupcakes';
import Monkeys from './monkeys';
import AddMonkeyForm from './add_monkey_form'
class UserDashboard extends Component {
// handleSubmit({name}) {
// console.log("handleSubmitMonkey with", {name})
// //this.props.createMonkey({user, name})
// }
render() {
return (
<div className="container">
<div className="section">
<h1>Hi: {this.props.user.name}</h1>
</div>
<div className="section">
<h2>Monkeys</h2>
<div className="row">
<div className="col m6 s12">
<h4>Add a new monkey</h4>
<AddMonkeyForm /> // If I take this out, everything works, it fails whether or not I add a handle submit function
</div>
<div className="col m6 s12">Existing monkeys</div>
</div>
</div>
<div className="section">
<h2>Cupcakes</h2>
<div className="row">
<div className="col m6 s12">Add a new cupcake</div>
<div className="col m6 s12">Existing cupcakes</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
const user = state.auth.user;
const cupcakes = state.userdata.cupcakes;
const monkeys = state.userdata.monkeys;
return { user: user, monkeys: monkeys, cupcakes: cupcakes };
}
export default connect(mapStateToProps, actions)(UserDashboard);
// <AddMonkeyForm onSubmit={this.handleSubmit.bind(this)}/>
AddMonkeyForm.js 导致错误 - 无论我尝试在 AddMonkeyForm 或 UserDashboard 中调用 handlesubmit 还是根本不调用,这个都会失败。
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import renderTextField from '../helpers/form_helpers';
import { createMonkey } from '../../actions';
class AddMonkeyForm extends Component {
onSubmit(values) {
console.log('trying to submit MONKEY');
// this.props.createMonkey(values, () =>{
// this.props.history.push('/');
// });
}
render() {
const { handleSubmit } = this.props;
return (
<div className="section">
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Name"
name="name"
placeholder="Fluffy"
component={renderTextField}
type="text"
/>
<button
className="btn-large dark-primary-color"
type="submit"
>
Add Monkey
<i className="material-icons right">done</i>
</button>
</form>
</div>
);
}
}
const validate = values => {
const errors = {};
if (!values.name) {
errors.name = 'Please enter monkey name';
}
return errors;
};
export default reduxForm({
form: 'addmonkey',
validate
})(AddMonkeyForm);
//})(connect(null, { createMonkey })(AddMonkeyForm));
actions.js中的动作,我最终会用这个
调用
export function createMonkey(userid, name) {
return function(dispatch) {
const url = `${USER_API_URL}/${userid}/monkey/new`;
const request = axios.post(url, {
headers: { authorization: `Bearer ${localStorage.getItem('token')}` },
name
});
request
.then(response => {
console.log("createMonkey has RESPONSE", response.data.createdMonkey)
dispatch({
type: GET_USER_MONKEYS,
payload: response.data.createdMonkey
});
})
// If request is bad...
// -Show an error to the user
.catch(() => {
console.log('error');
});
};
}
**usergetters.js reducer,最终将根据表单更新 userdata.monkeys 状态。
import { GET_USER_CUPCAKES, GET_USER_MONKEYS } from '../actions/types'
const initialUserData = [{cupcakes: [], monkeys: []}]
export default function userGetterReducer(state = initialUserData, action) {
switch (action.type) {
case GET_USER_CUPCAKES:
return {...state, cupcakes: action.payload}
case GET_USER_MONKEYS:
return {...state, monkeys: action.payload }
default:
return state
}
}
项目在 github。这个特定的错误分支是 addmonkeyform1
如果由于某种原因你最终在 master 上,它看起来会与这里显示的不同。 Go to Project on Github
我把这个项目拉下来了,正试图找到多次调用的来源。我不确定它是从哪里来的。如果我有进一步的发现,我会更新。
与此同时,您可以在 App.js 中执行以下操作:
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate');
return nextState !== this.state;
}
如果状态没有改变,这将阻止 re-rendering。
您在呈现表单后立即调用 handleSubmit(...)。我假设你只想在实际提交表单时调用它,所以你应该更改这一行:
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
像这样:
<form onSubmit={(values) => methodYouWantToCallWhenTheFormIsSubmitted(values)}>
我总体上使用的是 MERN 堆栈,但我认为这个问题仅适用于 React 和 redux 形式。
每当我在我的用户仪表板中包含一个表单来添加一个项目时,我最终得到
Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
首先,我根本没有显式调用 componentWillUpdate 或 componentDidUpdate,所以我很难找到问题所在。如果我停止开发服务器,比如 CTRL+C
它有时会为我呈现(现在无法使用的)表单。
我试过了(都失败了):
- 只包含没有处理程序的表单
- 包含表格并在仪表板上处理
- 包含表格并在表格上处理
- 基于此 somewhat similar problem 删除对
bind(this)
的所有调用
我有类似的 redux-forms(在它们的容器中处理),可以很好地用于注册和登录
UserDashboard.js 当我添加表单时发生错误并且没有它时工作正常
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import * as actions from '../../actions';
import Cupcakes from './cupcakes';
import Monkeys from './monkeys';
import AddMonkeyForm from './add_monkey_form'
class UserDashboard extends Component {
// handleSubmit({name}) {
// console.log("handleSubmitMonkey with", {name})
// //this.props.createMonkey({user, name})
// }
render() {
return (
<div className="container">
<div className="section">
<h1>Hi: {this.props.user.name}</h1>
</div>
<div className="section">
<h2>Monkeys</h2>
<div className="row">
<div className="col m6 s12">
<h4>Add a new monkey</h4>
<AddMonkeyForm /> // If I take this out, everything works, it fails whether or not I add a handle submit function
</div>
<div className="col m6 s12">Existing monkeys</div>
</div>
</div>
<div className="section">
<h2>Cupcakes</h2>
<div className="row">
<div className="col m6 s12">Add a new cupcake</div>
<div className="col m6 s12">Existing cupcakes</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
const user = state.auth.user;
const cupcakes = state.userdata.cupcakes;
const monkeys = state.userdata.monkeys;
return { user: user, monkeys: monkeys, cupcakes: cupcakes };
}
export default connect(mapStateToProps, actions)(UserDashboard);
// <AddMonkeyForm onSubmit={this.handleSubmit.bind(this)}/>
AddMonkeyForm.js 导致错误 - 无论我尝试在 AddMonkeyForm 或 UserDashboard 中调用 handlesubmit 还是根本不调用,这个都会失败。
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import renderTextField from '../helpers/form_helpers';
import { createMonkey } from '../../actions';
class AddMonkeyForm extends Component {
onSubmit(values) {
console.log('trying to submit MONKEY');
// this.props.createMonkey(values, () =>{
// this.props.history.push('/');
// });
}
render() {
const { handleSubmit } = this.props;
return (
<div className="section">
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Name"
name="name"
placeholder="Fluffy"
component={renderTextField}
type="text"
/>
<button
className="btn-large dark-primary-color"
type="submit"
>
Add Monkey
<i className="material-icons right">done</i>
</button>
</form>
</div>
);
}
}
const validate = values => {
const errors = {};
if (!values.name) {
errors.name = 'Please enter monkey name';
}
return errors;
};
export default reduxForm({
form: 'addmonkey',
validate
})(AddMonkeyForm);
//})(connect(null, { createMonkey })(AddMonkeyForm));
actions.js中的动作,我最终会用这个
调用export function createMonkey(userid, name) {
return function(dispatch) {
const url = `${USER_API_URL}/${userid}/monkey/new`;
const request = axios.post(url, {
headers: { authorization: `Bearer ${localStorage.getItem('token')}` },
name
});
request
.then(response => {
console.log("createMonkey has RESPONSE", response.data.createdMonkey)
dispatch({
type: GET_USER_MONKEYS,
payload: response.data.createdMonkey
});
})
// If request is bad...
// -Show an error to the user
.catch(() => {
console.log('error');
});
};
}
**usergetters.js reducer,最终将根据表单更新 userdata.monkeys 状态。
import { GET_USER_CUPCAKES, GET_USER_MONKEYS } from '../actions/types'
const initialUserData = [{cupcakes: [], monkeys: []}]
export default function userGetterReducer(state = initialUserData, action) {
switch (action.type) {
case GET_USER_CUPCAKES:
return {...state, cupcakes: action.payload}
case GET_USER_MONKEYS:
return {...state, monkeys: action.payload }
default:
return state
}
}
项目在 github。这个特定的错误分支是 addmonkeyform1
如果由于某种原因你最终在 master 上,它看起来会与这里显示的不同。 Go to Project on Github
我把这个项目拉下来了,正试图找到多次调用的来源。我不确定它是从哪里来的。如果我有进一步的发现,我会更新。
与此同时,您可以在 App.js 中执行以下操作:
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate');
return nextState !== this.state;
}
如果状态没有改变,这将阻止 re-rendering。
您在呈现表单后立即调用 handleSubmit(...)。我假设你只想在实际提交表单时调用它,所以你应该更改这一行:
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
像这样:
<form onSubmit={(values) => methodYouWantToCallWhenTheFormIsSubmitted(values)}>