I have an input component that accepts input upto 5 characters. When the input length is more that 5, it shows a message Limit Exceeds (only upto 5 characters accepted)
.
Sample component code :
import { useEffect, useState } from "react";
export function ConditionalInput() {
const [inputInfo, setInputInfo] = useState({ value: "", lengthCount: 0 });
const [warningMessageVisible, setWarningMessageVisible] = useState(false);
useEffect(() => {
if (inputInfo.value.length > 5) {
setInputInfo((s) => ({ ...s, lengthCount: 0 }));
}
}, [inputInfo, warningMessageVisible]);
const onChange = ({ target }) => {
setInputInfo((s) => ({ ...s, value: target.value }));
if (target.value.length > 5) {
setWarningMessageVisible(true);
}
};
return (
<div>
<input type="text" value={inputInfo.value} onChange={onChange} />
<div>Number of secrets: {inputInfo.lengthCount}</div>
{warningMessageVisible && (
<h3>Limit Exceeds (only upto 5 characters accepted)</h3>
)}
</div>
);
}
On the UI everything looks ok but in the console I can see an error message printing in an infinite loop stating - Maximum update depth exceeded
Note - Above code is not the actual code I'm using but a mock of it. It have the same error and working
How can I fix this error showing in console? any advise or answer is appreciated
CodePudding user response:
You need to do the following changes in your code :
- remove inputInfo from useEffect dependencies
- instead of using
infoInput.lengthCount
useinfoInput.value.length
to show the length count.
Below is the working code
import { useEffect, useState } from "react";
export function ConditionalInput() {
const [inputInfo, setInputInfo] = useState({ value: "", lengthCount: 0 });
const [warningMessageVisible, setWarningMessageVisible] = useState(false);
useEffect(() => {
if (inputInfo.value.length > 5) {
setInputInfo((s) => ({ ...s, lengthCount: 0 }));
}
}, [warningMessageVisible]);
const onChange = ({ target }) => {
setInputInfo((s) => ({ ...s, value: target.value }));
if (target.value.length > 5) {
setWarningMessageVisible(true);
}
};
return (
<div>
<input type="text" value={inputInfo.value} onChange={onChange} />
<div>Number of secrets: {inputInfo.value.length}</div>
{warningMessageVisible && (
<h3>Limit Exceeds (only upto 5 characters accepted)</h3>
)}
</div>
);
}
CodePudding user response:
It's because of the dependencies array you've added setInputInfo
Your useEffect will trigger whenever there is a change in the inputInfo
. And inside the useEffect you're modifying the inputInfo
. So basically it's creating an infinite loop which will keep rendering the view.
To fix that you can remove inputInfo
from the dependency array of your useEffect.
CodePudding user response:
This issue happen from this useEffect
useEffect(() => {
if (inputInfo.value.length > 5) {
setInputInfo((s) => ({ ...s, lengthCount: 0 }));
}
}, [inputInfo, warningMessageVisible]);
This useEffect alway run when inputInfo
change. So you need to remove the inputInfo
at this useEffect
like this:
useEffect(() => {
if (inputInfo.value.length > 5) {
setInputInfo((s) => ({ ...s, lengthCount: 0 }));
}
}, [warningMessageVisible]);