I'm working on this component and I want to validate its fields before every render. If they are not valid I want to disable a button in the parent.
Here is what I've got thus far:
export default function Input(props) {
const [inputs] = useState(props.inputs);
const didChangeRef = useRef([]);
useEffect(() => {
if (!_.isEqual(didMountRef.current, props.inputs)) {
validateInput(input);
didChangeRef.current = props.inputs;
}
});
const validateInput = input => {
const errors = useValidation(input);
if(Object.keys(errors).length !== 0) {
props.setIsValid(false);
}
}
return (
<input
onChange={e=> props.setProperty(e)}>
</input>
<input
onChange={e=> props.setProperty(e)}>
</input>
)
}
If an input is changed, it sets a property in the parent and this component is re-rendered. Inputs is an array of objects and I wish to validate it's contents on each render (or componentDidMount). I either manage to get it to loop infinitely or run the validation only once.
I appreciate your help.
P.S.:
I tried another approach as well, but it still ends up looping infinately:
export default function Input(props) {
const didMountRef = useRef(true);
useLayoutEffect(() => {
if (didMountRef.current) {
didMountRef.current = false;
return;
}
validate(input);
});
const validate = input => {
// validation...
}
}
Here is the parent component:
class CreateShoppingItem extends React.Component {
constructor(props) {
super(props);
this.state = {
storage: {},
isValid: true,
};
}
setIsValid = (isValid) => {
this.setState({ isValid });
};
render() {
return (
<div>
<Input setIsValid={this.setIsValid} inputs={this.storage.inputs} />
<Button disable={!isValid}></Button>
</div>
);
}
}