We get a formData object from the server that we allow the user to edit and we are using lodash ._set-object to update parts of that formData depending on what part of the formData the user updates.
We are trying to control the state of formData in redux state. We try to use componentWillReceiveProps, but can't get the updated state back as a props. We put our action in onChange function and it changes the state correctly when we type in text. But when we finish typing it return back to empty string value as it can't get updated state to the component as a props, and then the onChange function triggers the action once again because value of the input is empty.
We are trying to get the current value locally by setting the state inside the component but getting this error;
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
This is our function;
onChange = ({ formData }) => {
const { path, editKeyword } = this.props;
const inputValue =formDataData[editKeyword];
let prevformData = this.props.formData;
// update the object using
const updatedFormData = _.set(prevFormData, path, inputValue);
// action
this.props.setCurrentFormData(updatedformData);};
We also tried the following with no luck;
onChange = ({ formData }) => {
const { path, editKeyword } = this.props;
const inputValue = formData[editKeyword];
console.log("input value ", inputValue);
let prevFormData = this.props.formData;
const updatedFormData = _.set(prevformData, path, inputValue);
// when we try to update local state
this.setState({ FormData: updatedformData})
};
Anyone encountered anything similar? We can't directly use the formData from the form-input because we are merging values from server and the user input.
@mikaelmh The React error that you have pasted is usually caused by calling an event handler/callback instead of assigning it, for example:
class Clicker extends React.Component {
constructor() {
super()
this.state = {
on: true
}
this.handler = this.handler.bind(this)
}
handler() {
this.setState({ on: !this.state.on })
}
render() {
return <button onClick={this.handler()}>Click me</button>
}
}
You can see a live version of this here https://codesandbox.io/s/2pr78pv3pp
The solution to this problem is to change the handler to an assignment:
render() {
return <button onClick={this.handler}>Click me</button>
}
Can you post the render method where you are rendering the form, or post a minimal reproduction in https://codesandbox.io or somewhere similar?
@LucianBuzzo apologize for our late reply. We have been able to make a sandbox that you can have a look at ;
https://codesandbox.io/s/oo3qknl296
Our requirement is that we will receive initial state of formData from the server, and we need to update a specific part of it using the path only (e.g. task[0].title or task.title like it would be in the example). We achieved that functionality and put it in onChange function as you can see in the sandbox. However, If you uncomment where we are trying to set the updated state, you see the error Maximum update depth exceded...
Thoughts on how we can do this correctly? Thank you.
@mikaelmh I looked at the sandbox you made and I think the issue comes down to the way that you are controlling the <Form /> component. It seems that setting formData to an empty string at the bottom of onChange() causes this error. If you change the method to this it should work as expected:
onChange = ({ formData }) => {
const { path, editKeyword } = this.props;
const inputValue = formData[editKeyword];
// console.log("input value ", inputValue);
let prevFormData = this.props.formData;
const updatedFormData = _.set(prevFormData, path, inputValue);
this.props.updateForm(formData);
this.setState({ formData });
};
For a completely minimal reproduction of this issue take a look at this:
https://codesandbox.io/s/yk6w0z9qxz
It appears that setting formData to any falsey value will cause the error Maximum update depth exceeded....
Setting it to a truthey value (non-empty string, true, empty object etc) will not cause the same behaviour.
The issue is here https://github.com/mozilla-services/react-jsonschema-form/blob/master/src/utils.js#L190 - When a Form is updated, it checks computed formData against the formData prop, if there is a difference, then the onChange handler is called. If the formData value is falsey, then the this will result in an infinite loop, as the computed formData and props.formData will never be the same.
Update: I've opened a PR to fix this issue
@LucianBuzzo thank you, this was great! We were able to make it work this past weekend. Awesome feedback.
Most helpful comment
The issue is here https://github.com/mozilla-services/react-jsonschema-form/blob/master/src/utils.js#L190 - When a
Formis updated, it checks computedformDataagainst theformDataprop, if there is a difference, then theonChangehandler is called. If theformDatavalue is falsey, then the this will result in an infinite loop, as the computedformDataandprops.formDatawill never be the same.Update: I've opened a PR to fix this issue