Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Redux, rerendering after data was fetched and mapped into component?

Hi I am having trouble with getting data fetched and available as this.props.data to pass into a child component <GoogleMaps /> and rerendering when the data has changed.

It only works the first time the form is submitted and data is fetched but not again. The new data is not available since the render() function calls {this.renderMap(this.props.data)} before {this.renderData()}, which fetches and returns and maps the data.

I tried switching them but it looks like the render() function is not waiting until data is fetched before calling {this.renderMap(this.props.data)}. Should I be passing the data to the GoogleMap component a different way that allows it to reload with new data before rendering?

My renderData(); works fine, which returns component ListItem. It works every time my form is submitted. The problem is getting GoogleMaps component to be aware of this change and re-rendering?

class Feature extends Component {

    handleFormSubmit({ term, location }) {
        this.props.fetchData( { term, location });
        this.setState({showMap: true});
    }
    renderData() {
        return this.props.data.map((data) => {
            return (
                <ListItem
                    key={data.id}
                    data={data} />
            )
        });
    }
    renderMap(data) {
        if (this.state.showMap == true) {
            const lon = data[0].location.coordinate.longitude;
            const lat = data[0].location.coordinate.latitude;
        return (
            <GoogleMap 
               data={data} 
               lon={lon} 
               lat={lat} />
        )
        }
    }
    render() {
        const { handleSubmit, fields: { term, location }} = this.props;
        return (
            <div>
                <div>
                    <form className="form-inline" onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
                        <fieldset className="form-group">
                            <label>Find:</label>
                            <input className="form-control" {...term} />
                        </fieldset>
                        <fieldset className="form-group">
                            <label>Location:</label>
                            <input className="form-control" {...location} />
                        </fieldset>
                        <button action="submit" className="btn btn-primary">Search</button>
                    </form>
                </div>
                <div className="map_container">
                {this.renderMap(this.props.data)}
                </div>
                <ul className="list-group">
                {this.renderData()}
                </ul>
            </div>
        )
    }
}

function mapStateToProps(state) {
    return { data: state.data };
}

export default reduxForm({
    form: 'search',
    fields: ['term', 'location']
}, mapStateToProps, actions)(Feature);

Here is the fetchData function, I am getting the data fine.

export function fetchData( {term, location} ) {
    return function(dispatch) {
        axios.post(`${ROOT_URL}/data`, {term, location})
        .then(response => {
            dispatch({ 
                type: FETCH_DATA,
                payload: response 
            })
        })
    }
}
like image 230
Eric Tran Avatar asked May 19 '16 23:05

Eric Tran


People also ask

Why is my component Rerendering React?

React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.

What can retrieve updated state and re-render again?

The root reducer function is called with the current state and the dispatched action. The root reducer may divide the task among smaller reducer functions, which ultimately returns a new state. The store notifies the view by executing their callback functions. The view can retrieve updated state and re-render again.

How do I stop component Rerendering?

If you're using a React class component you can use the shouldComponentUpdate method or a React. PureComponent class extension to prevent a component from re-rendering.


1 Answers

Finally solved this. ComponentsWillReceiveProps did the trick. Had to call ComponentsWillReceiveProps with nextProps and call setState to set the data to nextProps.data.

This allowed me to use the data to render the GoogleMaps lat long coordinates and set each marker.

like image 63
Eric Tran Avatar answered Oct 05 '22 04:10

Eric Tran