Skip to content Skip to sidebar Skip to footer

React/Redux Animations Based On Actions

Having more or less completed my first React+Redux application, I have come to the point where I would like to apply animations to various parts of the application. Looking at exis

Solution 1:

I hope I understood everything right… Dealing with React + Redux means, that in best case your components are pure functional. So a component that should be animated should (IMHO) at least take one parameter: p, which represents the state of the animation. p should be in the interval [0,1] and zero stands for the start, 1 for the end and everything in between for the current progress.

const Accordion = ({p}) => {
  return (
    …list of items, each getting p
  );
}

So the question is, how to dispatch actions over time (what is an asynchronous thing), after the animation started, until the animation is over, after a certain event triggered that process.

Middleware comes in handy here, since it can »process« dispatched actions, transform them into another, or into multiple

//middleware/animatror.js

const animator = store => next => action => {
  if (action.type === 'animator/start') {

    //retrieve animation settings 
    const { duration, start, … } = action.payload;

    animationEngine.add({
      dispatch,
      action: {
       progress: () => { … },
       start: () => { … },
       end: () => { … }
      }
    })
  } else {
    return next(action);
  }
}

export default animator;

Whereby the animationEngine is an Instance of AnimatoreEngine, an Object that listens to the window.requestAnimationFrame event and dispatches appropriate Actions. The creation of the middleware can be used the instantiate the animationEngine.

const createAnimationMiddleware = () => {
  const animatoreEngine = new AnimatorEngine;

  return const animator = store => next => action => { … }

}

export default createAnimationMiddleware;

//store.js
const animatorMiddleware = createAnimationMiddleware();

…

const store = createStore(
  …,
 applyMiddleware(animatorMiddleware, …)
)

The basic Idea is, to »swallow« actions of type animator/start, or something else, and transform them into a bunch of »subactions«, which are configured in the action.payload.

Within the middleware, you can access dispatch and the action, so you can dispatch other actions from there, and those can be called with a progress parameter as well.

The code showed here is far from complete, but tried to figure out the idea. I have build »remote« middleware, which handles all my request like that. If the actions type is get:/some/path, it basically triggers a start action, which is defined in the payload and so on. In the action it looks like so:

const modulesOnSuccessAction => data {
  return {
    type: 'modules/listing-success',
    payload: { data }
  }
}

const modulesgetListing = id => dispatch({
  type: `get:/listing/${id}`,
  payload: {
    actions: {
      start: () => {},
      …
      success: data => modulesOnSuccessAction(data)
    }
  }
});

export { getListing }

So I hope I could transport the Idea, even if the code is not ready for Copy/Paste.


Post a Comment for "React/Redux Animations Based On Actions"