Winterest / Dark mode with redux and react hook
I recorded my code how I implemented dark mode in Winterest.
npm install styled-components styled-theming redux react-redux
- styled-components
- styled-theming
- redux and react-redux
What I built
./theme.js
I seperated light mode and dark mode of the color values.
//./theme.js
const theme = {
light: {
background: '#FFFEFC',
fontColor: '#2D2B2B',
red: '#e60023',
darkRed: '#ad081b',
...
},
dark: {
background: '#2D2B2B',
fontColor: '#fafafa',
red: '#e60023',
darkRed: '#ad081b',
...
},
};
export default theme;
./styles/DarkThemeProvider.js
import { useSelector } from 'react-redux';
import { ThemeProvider } from 'styled-components';
import theme from './theme';
const DarkThemeProvider = ({ children }) => {
const darkThemeEnabled = useSelector(state => state.darkMode.isDarkMode);
return (
<ThemeProvider theme={darkThemeEnabled ? theme.dark : theme.light}>
{children}
</ThemeProvider>
);
};
export default DarkThemeProvider;
./styles/GlobalStyle.js
import { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
body {
background-color: ${props => props.theme.background};
font-family: 'Noto Sans KR', Arial, Helvetica, sans-serif;
}
`;
export default GlobalStyle;
./redux/index.js
import { combineReducers } from 'redux';
import darkMode from './darkmode';
const rootReducer = combineReducers({
darkMode,
});
export default rootReducer;
./redux/darkmode.js
const initialState = { isDarkMode: false };
//actions
const DARK_MODE = 'toggle/DARKTHEME';
export const toggleDarkTheme = () => ({ type: DARK_MODE });
export default function darkModeReducer(state = initialState, action) {
switch (action.type) {
case DARK_MODE:
return { isDarkMode: !state.isDarkMode };
default:
return state;
}
}
./index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import GlobalStyle from './styles/GlobalStyle';
import Routers from './Routers';
import DarkThemeProvider from './styles/DarkThemeProvider';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<DarkThemeProvider>
<GlobalStyle />
<Routers />
</DarkThemeProvider>
</Provider>,
document.getElementById('root')
);
./store.js
Here is magic that save your state of the darkmode in your local storage.
import { createStore } from 'redux';
import rootReducer from './redux/index';
const localStorageKey = 'theme';
const persistedTheme = localStorage.getItem(localStorageKey);
let initialState = {
darkMode: persistedTheme ? JSON.parse(persistedTheme) : {},
};
const store = createStore(rootReducer, initialState);
store.subscribe(() => {
const preferences = store.getState().darkMode;
if (!preferences) return;
localStorage.setItem(localStorageKey, JSON.stringify(preferences));
});
export default store;
./components/Nav.js Button for the dark mode
The dark mode button placed on the navigation.
import { useSelector, useDispatch } from 'react-redux';
...
const isDarkTheme = useSelector(state => state.darkMode.isDarkMode);
const dispatch = useDispatch();
const toggleDarkMode = () => {
dispatch(toggleDarkTheme());
};
...
<Icon onClick={toggleDarkMode}>
{isDarkTheme ? (
<MdWbSunny style={buttonStyle} />
) : (
<MdStarOutline style={buttonStyle} />
)}
</Icon>
...
Resource
- Mainly inspired by blog, Implementing a dark theme toggle with react-redux and styled-components
- Wecode
- This code is for my Winterest project, the Pinterest cloning project
- Winterest website published using AWS S3
- Demo video
- Showcase recorded on the final presentation of the project on 26th Nov 2021
- Front-end github
- Trello