Redux Async Actions

Redux Async Actions

by Hemanth HM

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.0.5/redux.min.js"></script>
<div class="cartoon">
  <div class="spinner"></div>
  <img id="xkcd" src="" alt="">
</div>

CSS

.spinner {
  width: 40px;
  height: 40px;
  background-color: #333;
  display: "none";
  margin: 100px auto;
  -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
  animation: sk-rotateplane 1.2s infinite ease-in-out;
}

@-webkit-keyframes sk-rotateplane {
  0% {
    -webkit-transform: perspective(120px)
  }
  50% {
    -webkit-transform: perspective(120px) rotateY(180deg)
  }
  100% {
    -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg)
  }
}

@keyframes sk-rotateplane {
  0% {
    transform: perspective(120px) rotateX(0deg) rotateY(0deg);
    -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
  }
  50% {
    transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
    -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
  }
  100% {
    transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
    -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
  }
}

Babel + JSX

const render = function(state) {
  let xkcd = document.querySelector('#xkcd');
  let spinner = document.querySelector('.spinner');
  // show hide spinner
  spinner.style.display = state.loading ? "block" : "";
  // set src and alt
  xkcd.src = state.comic.url;
  xkcd.alt = state.comic.title;

  // hide spinner on img load
  xkcd.addEventListener('load', () => {
    spinner.style.display = 'none';
  })
}

const initialState = {
  loading: false,
  error: false,
  comic: null
}

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'FETCHING_COMIC':
      return {
        ...state,
        fetching: true,
          comic: action.comic
      }
    case 'FETCH_COMIC_SUCCESS':
      return {
        ...state,
        fetching: false,
          comic: action.comic
      }
    case 'FETCH_COMIC_FAILED':
      return {
        ...state,
        fetching: false,
          error: action.error
      }
  }
}

const store = Redux.createStore(reducer);

store.dispatch({
  type: 'FETCHING_COMIC'
})

fetch('https://xkcd-imgs.herokuapp.com/')
  .then(response => response.json())
  .then(comic => {
    store.dispatch({
      type: 'FETCH_COMIC_SUCCESS',
      comic
    })
  })
  .catch(error => store.dispatch({
    type: 'FETCH_COMIC_FAILED',
    error
  }))

store.subscribe(() => render(store.getState()))