@soyguijarro
Web developer from Madrid
JavaScript and React enthusiast
Silly pet projects expert
Controversial tech speaker
import { applyMiddleware, createStore, compose } from "redux";
import thunkMiddleware from "redux-thunk";
import rootReducer from "./reducers";
export default preloadedState => {
const middlewares =
process.env.NODE_ENV !== "production"
? [require("redux-immutable-state-invariant").default(), thunkMiddleware]
: [thunkMiddleware];
const composeEnhancers =
typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
: compose;
const composedEnhancers = composeEnhancers(applyMiddleware(...middlewares));
return createStore(rootReducer, preloadedState, composedEnhancers);
};
export const addFavorite = id => ({
type: ADD_FAVORITE,
id
});
const favoriteIdsReducer = (state = [], action) => {
switch (action.type) {
case ADD_FAVORITE:
…
};
export default favoriteIdsReducer;
return state.includes(action.id) ?
state :
[...state, action.id];
return [
...state.slice(0, action.index),
...state.slice(action.index + 1)
];
return [
...state.slice(0, action.index),
action.id,
...state.slice(action.index + 1)
];
return {
...state,
[action.id]: {
...state[action.id],
data: action.data
}
};
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { getMovieById, fetchMovie } from "../store/reducers";
const Movie = ({ id, movie, fetchMovie }) => {
…
useEffect(() => {
fetchMovie(id));
}, [id]);
…
}
export default connect(
(state, ownProps) => ({
movie: getMovieById(state, ownProps.id),
}),
{ fetchMovie }
)(Movie);
import React, { createContext, useContext, useReducer } from "react";
const StoreContext = createContext();
const StoreProvider = ({ children }) => {
const [state, dispatch] = useReducer(rootReducer, initialState);
return (
<StoreContext.Provider value={[state, dispatch]}>
{children}
</StoreContext.Provider>
);
};
export const useStore = () => useContext(StoreContext);
export default StoreProvider;
import React from "react";
import StoreProvider from "./store";
const App = () => <StoreProvider>…</StoreProvider>;
export default App;
import React from "react";
import { useStore, ACTIONS } from "./store";
const Favorites = () => {
const [state, dispatch] = useStore();
const {favoriteIds} = state;
…
dispatch({type: ACTIONS.ADD_FAVORITE, payload: id});
…
};
export default Favorites;
import React, { createContext, useContext, useReducer } from "react";
const FavoritesContext = createContext();
const FavoritesProvider = ({ children }) => {
const [favoriteIds, dispatch] = useReducer(favoriteIdsReducer, []);
return (
<FavoritesContext.Provider value={[favoriteIds, dispatch]}>
{children}
</FavoritesContext.Provider>
);
};
export const useFavorites = () => useContext(FavoritesContext);
export default FavoritesProvider;
import React from "react";
import { useFavorites, ACTIONS } from "./context/favorites";
const Favorites = () => {
const [favoriteIds, dispatch] = useStore();
…
dispatch({type: ACTIONS.ADD_FAVORITE, payload: id});
…
};
export default Favorites;
…
export const useFavorites = () => {
const [favoriteIds, dispatch] = useContext(FavoritesContext);
const addFavorite = id => {
dispatch({type: ACTIONS.ADD_FAVORITE, id});
};
…
return [favoriteIds, {addFavorite, …}];
};
…
import React from "react";
import { useFavorites } from "./context/favorites";
const Favorites = () => {
const [favoriteIds, {addFavorite}] = useStore();
…
addFavorite(id);
…
};
export default Favorites;
…
export const useMovies = () => {
const [moviesById, dispatch] = useContext(MoviesContext);
const fetchMovie = async id => {
dispatch({ type: ACTIONS.REQUEST_MOVIE, id });
const data = await api.fetchMovie(id);
dispatch({ type: ACTIONS.RECEIVE_MOVIE, id, data });
};
return [moviesById, { fetchMovie }];
};
…
…
export const useMovie = id => {
const [moviesById, { fetchMovie }] = useMovies();
return [
movie: moviesById[id],
{ fetchMovie: () => fetchMovie(id) },
];
};
…
import React, { useEffect } from "react";
import { useMovie } from "../context/movies";
const Movie = ({ id }) => {
const [movie, { fetchMovie }] = useMovie(id);
…
useEffect(() => {
fetchMovie();
}, []);
…
};
export default Movie;
import { applyMiddleware, createStore, compose } from "redux";
import thunkMiddleware from "redux-thunk";
import rootReducer from "./reducers";
export default preloadedState => {
const middlewares =
process.env.NODE_ENV !== "production"
? [require("redux-immutable-state-invariant").default(), thunkMiddleware]
: [thunkMiddleware];
const composeEnhancers =
typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
: compose;
const composedEnhancers = composeEnhancers(applyMiddleware(...middlewares));
return createStore(rootReducer, preloadedState, composedEnhancers);
};
import { configureStore } from "redux-starter-kit";
import rootReducer from "./reducers";
export default preloadedState =>
configureStore({
reducer: rootReducer,
preloadedState
});
const ADD_FAVORITE = "ADD_FAVORITE"
export const addFavorite = id => ({ type: ADD_FAVORITE, id });
…
const favoriteIdsReducer = (state = [], action) => {
switch (action.type) {
case ADD_FAVORITE:
return state.includes(action.id) ?
state :
[...state, action.id];
…
default:
return state;
}
};
export default favoriteIdsReducer;
import { createAction, createReducer } from 'redux-starter-kit';
export const addFavorite = createAction("ADD_FAVORITE")
…
const favoriteIdsReducer = createReducer([], {
[addFavorite]: (state, action) => {
if (!state.includes(action.payload)) {
state.push(action.payload);
}
},
…
});
export default favoriteIdsReducer;
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { getMovieById, fetchMovie } from "../store/reducers";
const Movie = ({ id, movie, fetchMovie }) => {
…
useEffect(() => {
fetchMovie(id));
}, [id]);
…
}
export default connect(
(state, ownProps) => ({
movie: getMovieById(state, ownProps.id),
}),
{ fetchMovie }
)(Movie);
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { getMovieById, fetchMovie } from "../store/reducers";
const Movie = ({ id }) => {
const movie = useSelector(state => getMovieById(state, id));
const dispatch = useDispatch();
…
useEffect(() => {
dispatch(fetchMovie(id));
}, [id]);
…
};
export default Movie;
import React, { useEffect } from "react";
import { useMovie } from "../context/movies";
const Movie = ({ id }) => {
const [movie, { fetchMovie }] = useMovie(id);
…
useEffect(() => {
fetchMovie();
}, []);
…
};
export default Movie;
@soyguijarro