Reputation: 20107
In my React + Redux + Redux-Form app, I need to enable/disable a "Next" button depending on the validity state of the form. This button is controlled by the parent component, so I can't just have <Button disabled={!props.valid}/>
. Ideally redux-form would give me an event like onValidityChanged
that I could listen for, and call the setCompleted()
function passed down by the parent component whenever this happens. However such an event doesn't seem to exist. I also can't use the onChange
hook, because at this point it won't have access to the props passed by the parent.
e.g.
function Parent(props){
const [completed, setCompleted] = React.useState(false);
return (
<div>
<Child setCompleted=setCompleted/>
<button disabled={!completed}>Next</button>
</div>
);
}
const Child = reduxForm({form: 'form'})(props => {
const {setCompleted} = props;
// Call setCompleted once this form becomes valid
});
How can I run an event whenever the validity of the form changes, but still have access to props?
Upvotes: 0
Views: 475
Reputation: 231
One simple way of doing so would be to read the current validity status as Redux-Form updates it in your redux state, using a selector. You can even use one provided by the redux-form
package: isValid
. Since you're using hooks, you can also use react-redux
's useSelector
hook (if you're using react-redux v7.1.0 or higher).
The result would be:
import { useSelector } from 'react-redux`;
import { reduxForm, isValid } from 'redux-form`;
const Child = reduxForm({form: 'form'})(props => {
const { setCompleted } = props;
const isFormValid = useSelector(state => isValid('form')(state));
// Call setCompleted once this form becomes valid
if (isFormValid) {
setCompleted(true);
}
});
Of course you may want to extract this selector in another file and memoize it.
You may also want to use this hook (or its mapStateToProps
equivalent) directly inside the parent component to avoid using the useState
hook in the first place.
Upvotes: 1