Search code examples
react-nativereduxreact-reduxredux-thunkreducers

I am using redux in react native application to fetch and display data but its not updating on data change from backend


I am using Redux in my React-Native application. I am fetching the data from api call and on success rendoring it on ListItem. I am able to fetch and display data but data is not auto updating unless and until I revisit the page. Even values are not storing into the app I am calling method from actions in constructor and componentDidMount method. Can you Please check the code and tell me where am I going wrong.

Here is action.js

import { 
    FETCHING_PRODUCT_REQUEST, 
    FETCHING_PRODUCT_SUCCESS, 
    FETCHING_PRODUCT_FAILURE 
} from './types';

export const fetchingProductRequest = () => ({
    type : FETCHING_PRODUCT_REQUEST
});

export const fetchingProductSuccess = (json) => ({
    type : FETCHING_PRODUCT_SUCCESS,
    payload : json
});

export const fetchingProductFailure = (error) => ({
    type : FETCHING_PRODUCT_FAILURE,
    payload : error
});

export const fetchProduct = () => {
    return async dispatch => {
        dispatch(fetchingProductRequest());
        try {
            let response = await fetch("http://phplaravel-325095-1114213.cloudwaysapps.com/api/shop/shop");
            let json = await response.json();
            dispatch(fetchingProductSuccess(json));
        } catch(error) {
            dispatch(fetchingProductFailure(error));
        }
    }
}

My reducer.js

import { 
    FETCHING_PRODUCT_REQUEST, 
    FETCHING_PRODUCT_SUCCESS, 
    FETCHING_PRODUCT_FAILURE 
} from './../actions/types';

const initialState = {
    loading : false,
    errorMessage : '',
    shops: []
}

const products = ( state = initialState, action ) => {
    switch(action.type) {
        case FETCHING_PRODUCT_REQUEST :
            return { ...state, loading: true} ;
        case FETCHING_PRODUCT_SUCCESS : 
            return { ...this.state, loading: false, shops: action.payload };
        case FETCHING_PRODUCT_FAILURE : 
            return { ...state, loading: false, errorMessage: action.payload};
    }
};

export default products;

product.js

import * as React from 'react';

import { FlatList , ActivityIndicator} from 'react-native';

import { ListItem } from 'react-native-elements';

import { fetchProduct } from './../../actions/products';

import { connect } from 'react-redux';

import propTypes from 'prop-types';

class Product extends React.Component {

  constructor(props) {
    super(props);
    this.props.fetchProduct();
    this.state = {
      loading : true,
      shops : '',
     isFetching: false,
     active : true,
    }
   }


   fetchProducts() {
    const shopid = 13;
    fetch(`http://phplaravel-325095-1114213.cloudwaysapps.com/api/shop/shop`)
        .then(response => response.json())
          .then((responseJson)=> {
              this.setState({
                 loading: false,
                 shops: responseJson
              })
             alert(JSON.stringify(this.state.shops));
        })
    .catch(error=>console.log(error)) //to catch the errors if any
   }

    componentDidMount(){
      // this.fetchProducts();
      this.props.fetchProduct().then(this.setState({loading : false}));
    }



  renderItem = ({ item }) => (
  <ListItem
    title={item.name}
    subtitle={item.name}
    leftAvatar={{
      source: item.avatar && { uri: item.avatar },
      title: item.name[0]
    }}
    bottomDivider
    chevron
  />
)

render () {
    if(!this.state.loading)
    { 
      if(this.props.shopsInfo.loading)
      {
        return (
        <ActivityIndicator/>
        )
      }
      else
      {
        return (
        <FlatList
                vertical
                showsVerticalScrollIndicator={false}
                data={this.props.shopsInfo.shops}
                renderItem={this.renderItem}
              />
      )
      }
    }
    else
    {
      return (
        <ActivityIndicator/>
        )
    }
  }
}

Product.propTypes = {
  fetchProduct:  propTypes.func.isRequired
};


const mapStateToProps = (state) => {
  return { shopsInfo: state };
}

function mapDispatchToProps (dispatch) {
  return {
    fetchProduct: () => dispatch(fetchProduct())
  }
} 

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

Solution

  • 1. Not updating on data change from backend.

    You have to call an api on regular interval to get updated data. Redux implementation doesn't mean it will fetch data from server whenever there is any change.

    2. Even values are not storing into the app

    If you are expecting redux will store data even if you will close/kill an application than it will not. You have persist data in-order to use it or store it in cache. Take a look at redux-persist