score:3

Accepted answer

The state does not update when I change the selections

This is because you are not dispatching a Redux action in your handleChange method, only in your handleSubmit method. Simply dispatching the appropriate action in handleChange will resolve this issue.

when I navigate away from the page, the state that was last stored is not retained

This is because the values from before (before you navigate away) will only be kept in the Redux store, while the form fields are populated from the local state of the SearchAdvanced component.

To solve this one well, you should get rid of your local state entirely. Instead only use the Redux store. Keeping both intact is unnecessary and breaks the 'Single Source of Truth' that Redux is meant for. I recommend you do away with the local state and only update the Redux state and then pass values to the form inputs from the Redux store (props for the component).

Regarding your note that you tried this, but get errors: you need to change anything like:

<input value={ this.state.formValues.someValue }/>

to

<input value={ this.props.formValues.someValue }/>

where formValues comes from the Redux store.

Update

Problem now is the line

this.props.setFormValues(this.props.formValues)

in handleChange. You're using the old formValues to update, so the store never actually updates. I think you want something like:

handleChange(event) {
    event.preventDefault();
    const { name, value, type, checked } = event.target;
    this.props.setFormValues({
        ...this.props.formValues,
        [name]: type === 'checkbox' ? checked : value
    });
}

So that you are updating the store's formValues with the input from the user. The ternary operator is necessary for checkbox inputs since the value of a checked checkbox is 'on' rather than true, but the checked attribute is true if checked.

Extra

It seems that you pass the dispatch method to the SearchAdvanced via props from the parent. You can (and should) do this more cleanly by using the second argument of connect, which is mapDispatchToProps. Here's an example:

const mapDispatchToProps = {
    getSearchResults,
    setSearchedOnce,
    setPageNum,
    setFormValues
}

export default connect(mapStateToProps, mapDispatchToProps)(SearchAdvanced);

Then you can just call any of these as methods that already have a dispatch bound to them. So

this.props.dispatch(setSearchedOnce(true))

becomes

this.props.setSearchedOnce(true)

and you can remove the passing of the dispatch from the parent component.

Docs on connect: https://github.com/reduxjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options


Related Query

More Query from same tag