score:0

If your using React 16.8 hooks should be a good option

Use effect = componentDidMount, componentDidUpdate, and componentWillUnmount combined

Example

import React, { useEffect } from 'react';
import { Provider } from 'react-redux';

import AppInitActions from './store/actions/awesomeactions';

function App() {
  useEffect(() => store.dispatch(AppInitActions.handleCoolAction()), []);
  return (
    <Provider store={store}>
   <!....<Myactions />....>
    </Provider>
  );
}

export default App;

score:0

For a given state structure:

{
 "PRODUCT-1": {
   id: "PRODUCT-1",
   reviews: [],
 }
}

1. Dispatch addReviewSuccess after posting the review

postSomething('SOME_API_ENDPOINT', { id, newReview })
  .then(() => addReviewSuccess(id, newReview));

addReviewSuccess = (id, newReview) => {
  const payload = {
    id,
    newReview,
  };

  dispatch(addReviewSuccess(payload));
}

2. Listen for ADD_REVIEW_SUCCESS in Reducer

The system can listen for ADD_REVIEW_SUCCESS action to add the review to the list of reviews for that specific product.

// Action
{
  type: 'ADD_REVIEW_SUCCESS',
  payload: {
    id: "PRODUCT-1",
    newReview: {
      message: 'some review',
    }
  }
}

// Reducer
case 'ADD_REVIEW_SUCCESS':
  const newReview = payload.newReview;
  const product = state.products[payload.id];

  return {
    ...state.products,
    [product.id]: {
      ...state.products[product.id],
      reviews: [
        ...state.products[product.id].reviews,
        newReview
      ]
    }
  };

3. Re-render component every ADD_REVIEW_SUCCESS

Then your component will re-render every time the product has new reviews. Take note of the key prop as this is very helpful for React's Reconciliation.

// Product
mapStateToProps(state) {
  const { products } = this.state;

  return {
    products,
  }
}

const ProductList = (products) => (
  <Products>
  { Object.values(products).map((product) => (
    <Product key={product.id}>
      <Reviews reviews={product.reviews} />
    </Products>
  )}
);

// Reviews
const Reviews = (reviews) => (
  { reviews.map((review) => (
    <Review>{review.message}</Review>
  )}
)

score:0

You can add a unique identifier to the data in the reducer.
That way the view will always update when the action is triggered, even if the result is unchanged.

Timestamps are pretty good, because you can use that value for other things (e.g. "last updated x time ago"), but you need to be careful about the time source or you could have some weird bugs.
Basically you need a monotonically increasing value, so for timestamps that would mean using performance.now().
You can also simply use an integer starting at 0 for the first action, and increment it for each new action.

The downside of course, is that if you display this data somewhere else, it will also re-render every time even when not needed. That means you will need to implement shouldComponentUpdate in this component to prevent this.

score:2

I've managed to simulate this kind of behavior by creating a new resetAction that resets the redux store, and a new variable on the reducer state called isSuccess.

This way, when your initial action succeeds, you set the isSuccess to true, then you catch the isSuccess on your respective Component and handle the logic you want (Redirects or state changes) and finally call the resetAction so the redux store comes back to normal.

I guess it's kinda clunky and not elegant but it works.


Related Query

More Query from same tag