kazuyahiko
kazuyahiko

Reputation: 343

How can I pass state to an action in React.js?

I have some state in my component that I want to pass to an action in React.js. How can I do this?

mycomponent.js

cityHandleUpdateInput() {
    this.setState({
        city: this.refs.city.refs.searchTextField.input.value
    })
    const { city } = this.state;
    this.props.fetchResCity(city)
}

myaction.js

export const fetchResCity = (city) => (dispatch, getState) =>  {
if (!getState().resCity.isFetching) {
    console.log(getState().city)
    console.log(city)
    const endpoint = 'rescity?city=${city}';
    dispatch({
        [CALL_API]: {
            types: [ RES_CITY_REQUEST, RES_CITY_SUCCESS, RES_CITY_FAILURE ],
            endpoint: endpoint
        }
    })
    }
}

It's not working. Is there something wrong in my code? When I log that city variable in my action it's just undefined.

Upvotes: 0

Views: 1053

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 282030

You should be using the setState callback i.e a correct way to handle state mutations since setState takes time to mutate the state and hence any use of state immediately after updating the state may result in the older value and not the updated value.

Make use of callback like

cityHandleUpdateInput() {
    this.setState({
        city: this.refs.city.refs.searchTextField.input.value
    }, () => {
        const { city } = this.state;
        this.props.fetchResCity(city)
    })  
}

Make sure that you are binding the cityHandleUpdateInput function in constructor or from where it is being called or otherwise it itself won't be able to access the setState with this.setState

Upvotes: 0

Jamison Dance
Jamison Dance

Reputation: 20184

setState won't immediately update this.state. Here is the explanation from the React docs:

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

That means you'd need to store the value you are passing to setState, and pass that to your action creator as well. Something like this (I didn't run this code, make sure you test it) should work:

cityHandleUpdateInput() {
    const city = this.refs.city.refs.searchTextField.input.value;
    this.setState({ city });
    this.props.fetchResCity(city);
}

Upvotes: 1

Related Questions