1

I am showing list of coupons based on category selected using useEffect and saga.

const initialState = {
    is_loading: true,
    coupon_data: [],
    error_msg: '',
} 

This is my initial state state. is_loading set to true default so that whenever component get visited it shows loader first, after that getCoupon() get dispatch from useEffect which hit api and get response asynchronously using redux-saga,then is_loading is set to false and based on response coupon_data or error_msg get updated.

this is component:

    const Couponlist = props => {
    const [coupon, updateCoupon] = useState(null);

    useEffect(() => {
        if (props.coupon.is_loading) {
            updateCoupon(<Loader />);
            props.getCoupon(props.match.params.category)
        } else if (!props.coupon.is_loading && props.coupon.coupon_data.length) {
            const coupon_data = props.coupon.coupon_data.map(coupon => {
                return (<div key={coupon.id} className="card" style={{ width: "18rem" }}>
                    <img className="card-img-top" src={coupon.banner}
                        alt={"Card image cap " + coupon.id} />
                    <div className="card-body">
                        <h5 className="card-title">Outlet : {coupon.outlet}</h5>
                        <p className="card-text">Category : {coupon.category}</p>
                        <p className="card-text">Merchant : {coupon.merchant}</p>
                        <p className="card-text">Price : {coupon.coupon_price}</p>
                        <p className="card-text">Valid From : {coupon.valid_from}</p>
                        <p className="card-text">Valid To : {coupon.valid_to}</p>
                        <p className="card-text">Trending : {coupon.trending}</p>
                    </div>
                </div>)
            })
            updateCoupon(coupon_data);
        } else if (!props.coupon.is_loading && props.coupon.error_msg !== '') {
            updateCoupon(props.coupon.error_msg);
        }

    }, [props.match.params.category, props.coupon])

    return coupon;
}
const mapStateToProps = state => {
    return { coupon: state.coupon };
}

const mapDispatchToProps = dispatch => {
    return {
        getCoupon: category => dispatch(getCouponeInit(category))
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(Couponlist);

When component get visited first time is_loading is true so if (props.coupon.is_loading) becomes true and component render loader and request api for data.

after getting data from api is_loading is set to false and component render coupon data.

Now the problem is when user click on another category Couponlist component get visited again but this time is_loading is set to false and also there is old data there in store. So in this case instaed of requesting for new data component simply render old available data.

How can I handle this condition ?

Paritosh Mahale
  • 1,238
  • 2
  • 14
  • 42
  • do `props.coupon.coupon_data` showing updated value in in useEffect? – RIYAJ KHAN May 18 '20 at 05:44
  • states `coupon_data` property get updated only once when app get initialise ( `is_loading` is set to true at that moment ) after that if user click on other category api does not get call due to `is_loading` and component simply render old data – Paritosh Mahale May 18 '20 at 05:51

1 Answers1

0

you can add function inside UseEffect to clean up your component, try to add that at the bottom of the function useEffect

() => { your clean up code here }
Wonkledge
  • 1,732
  • 7
  • 16