let’s scaffold a react app with vite and redux toolkit

npm init vite@latest my_react_app -- --template react
cd my_react_app
npm i @reduxjs/toolkit react-redux
npm run dev

App.js

export default function App() {
	return <h1>Demo</h1>;
}

import Provider from react-redux and configureStore from @reduxjs/toolkit to create a store and pass it to Provider as a prop named store to make it available to all components in the app.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';

const store = configureStore({
	reducer: {},
});

export default function App() {
	return <Provider store={store}>
		<h1>Demo</h1>
	</Provider>;
}

import createSlice from @reduxjs/toolkit to create a slice of the store and pass it’s reducer to the store.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { Provider } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
	name: 'counter',
	initialState: { value: 0 },
	reducers: {},
});

const store = configureStore({
	reducer: {
		counter: counterSlice.reducer,
	},
});

export default function App() {
	return <Provider store={store}>
		<h1>Demo</h1>
	</Provider>;
}

create a template of Counter component and use it in App component.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { Provider } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
	name: 'counter',
	initialState: { value: 0 },
	reducers: {},
});

const store = configureStore({
	reducer: {
		counter: counterSlice.reducer,
	},
});

export default function App() {
	return <Provider store={store}>
		<h1>Demo</h1>
		<Counter />
	</Provider>;
}

function Counter() {
	return <>
		<button>-</button>
		0
		<button>+</button>
	</>;
}

import useSelector from react-redux to select a value from the store in the component.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Provider, useSelector } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
	name: 'counter',
	initialState: { value: 0 },
	reducers: {},
});

const store = configureStore({
	reducer: {
		counter: counterSlice.reducer,
	},
});

export default function App() {
	return <Provider store={store}>
		<h1>Demo</h1>
		<Counter />
	</Provider>;
}

function Counter() {
	const count = useSelector(state => state.counter.value);

	return <>
		<button>-</button>
		{count}
		<button>+</button>
	</>;
}

add increment and decrement reducers to counterSlice.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { Provider, useSelector } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
	name: 'counter',
	initialState: { value: 0 },
	reducers: {
		increment: state => { state.value++; },
		decrement: state => { state.value--; },
	},
});


const store = configureStore({
	reducer: {
		counter: counterSlice.reducer,
	},
});

export default function App() {
	return <Provider store={store}>
		<h1>Demo</h1>
		<Counter />
	</Provider>;
}

function Counter() {
	const count = useSelector(state => state.counter.value);

	return <>
		<button>-</button>
		{count}
		<button>+</button>
	</>;
}

import and use useDispatch from react-redux to dispatch actions to the store.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { Provider, useSelector, useDispatch } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
	name: 'counter',
	initialState: { value: 0 },
	reducers: {
		increment: state => { state.value++; },
		decrement: state => { state.value--; },
	},
});

const store = configureStore({
	reducer: {
		counter: counterSlice.reducer,
	},
});

export default function App() {
	return <Provider store={store}>
		<h1>Demo</h1>
		<Counter />
	</Provider>;
}

function Counter() {
	const count = useSelector(state => state.counter.value);
	const dispatch = useDispatch();

	return <>
		<button>-</button>
		{count}
		<button>+</button>
	</>;
}

dispatch increment and decrement actions on click of the buttons.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { Provider, useSelector, useDispatch } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
	name: 'counter',
	initialState: { value: 0 },
	reducers: {
		increment: state => { state.value++ },
		decrement: state => { state.value-- },
	},
});

const store = configureStore({
	reducer: {
		counter: counterSlice.reducer,
	},
});

export default function App() {
	return <Provider store={store}>
		<h1>Demo</h1>
		<Counter />
	</Provider>;
}

function Counter() {
	const count = useSelector(state => state.counter.value);
	const dispatch = useDispatch();

	return <>
		<button onClick={() => dispatch(counterSlice.actions.decrement())}>
			-
		</button>
		{count}
		<button onClick={() => dispatch(counterSlice.actions.increment())}>
			+
		</button>
	</>;
}