Skip to content

Commit 739aea2

Browse files
First Commit
0 parents  commit 739aea2

File tree

18 files changed

+7763
-0
lines changed

18 files changed

+7763
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
.next

package-lock.json

Lines changed: 7378 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "nextjs-ssr",
3+
"version": "1.0.0",
4+
"description": "next-redux-wrapper-redux-thunk",
5+
"main": "index.js",
6+
"scripts": {
7+
"dev": "next dev",
8+
"build": "next build",
9+
"start": "next start"
10+
},
11+
"author": "MD FAZLUL KARIM",
12+
"license": "MIT",
13+
"dependencies": {
14+
"axios": "^0.19.2",
15+
"next": "^9.4.2",
16+
"next-redux-wrapper": "^6.0.0",
17+
"react": "^16.13.1",
18+
"react-dom": "^16.13.1",
19+
"react-redux": "^7.2.0",
20+
"redux": "^4.0.5",
21+
"redux-devtools-extension": "^2.13.8",
22+
"redux-persist": "^6.0.0",
23+
"redux-thunk": "^2.3.0"
24+
},
25+
"devDependencies": {
26+
"@babel/core": "^7.9.6",
27+
"@babel/node": "^7.8.7",
28+
"@babel/preset-env": "^7.9.6"
29+
}
30+
}

pages/_app.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import App from "next/app";
2+
import { wrapper } from "../store/store";
3+
import { useStore } from "react-redux";
4+
import { PersistGate } from "redux-persist/integration/react";
5+
6+
function MyApp({ Component, pageProps }) {
7+
const store = useStore((state) => state);
8+
return (
9+
<PersistGate persistor={store.__persistor} loading={<div>Loading</div>}>
10+
<Component {...pageProps} />
11+
</PersistGate>
12+
);
13+
}
14+
15+
export default wrapper.withRedux(MyApp);

pages/_document.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Document, { Head, Main, NextScript } from "next/document";
2+
3+
export default class MyDocument extends Document {
4+
render() {
5+
return (
6+
<html>
7+
<Head></Head>
8+
<body>
9+
<Main />
10+
<NextScript />
11+
</body>
12+
</html>
13+
);
14+
}
15+
}

pages/counter/index.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from "react";
2+
import { useSelector, useDispatch } from "react-redux";
3+
import { incrementCounter, decrementCounter } from "../../store/counter/action";
4+
5+
const Users = ({ users, error }) => {
6+
const globalState = useSelector((state) => state.counter.counter);
7+
const dispatch = useDispatch();
8+
9+
return (
10+
<section>
11+
<h1>GLOBAL COUNTER {globalState}</h1>
12+
<button onClick={() => dispatch(incrementCounter(globalState))}>
13+
Increment +
14+
</button>
15+
{" "}
16+
<button onClick={() => dispatch(decrementCounter(globalState))}>
17+
Decrement -
18+
</button>
19+
<br />
20+
21+
<p>
22+
Try to reload this page or open a new tab or view this page another
23+
time.
24+
<br />
25+
You will see the same value everytime. Because the global state is
26+
persistent and saved in the localstorage
27+
</p>
28+
</section>
29+
);
30+
};
31+
32+
export default Users;

pages/index.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from "react";
2+
import { useSelector, useDispatch } from "react-redux";
3+
import { incrementCounter, decrementCounter } from "../store/counter/action";
4+
import Link from "next/link";
5+
6+
function counter() {
7+
const globalState = useSelector((state) => state.counter.counter);
8+
const dispatch = useDispatch();
9+
10+
return (
11+
<>
12+
<h1>GLOBAL COUNTER {globalState}</h1>
13+
<button onClick={() => dispatch(incrementCounter(globalState))}>
14+
Increment +
15+
</button>
16+
{" "}
17+
<button onClick={() => dispatch(decrementCounter(globalState))}>
18+
Decrement -
19+
</button>
20+
<br />
21+
<br />
22+
<p>
23+
Try to reload this page or open a new tab
24+
<br />
25+
or view this page another time.
26+
<br />
27+
You will see the same value everytime.
28+
<br />
29+
Because the global state is persistent
30+
<br />
31+
and saved in the localstorage.
32+
</p>
33+
34+
<Link href="/counter">
35+
<a>Go to Counter Page</a>
36+
</Link>
37+
<br />
38+
<Link href="/ssg">
39+
<a>Go to a getStaticProps used page</a>
40+
</Link>
41+
<br />
42+
<Link href="/ssr">
43+
<a>Go to a getServerSideProps used Page</a>
44+
</Link>
45+
</>
46+
);
47+
}
48+
49+
export default counter;

pages/ssg/index.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import React from "react";
2+
import axios from "axios";
3+
import { useSelector, useDispatch } from "react-redux";
4+
import { incrementCounter, decrementCounter } from "../../store/counter/action";
5+
6+
const Users = ({ users, error }) => {
7+
const globalState = useSelector((state) => state.counter.counter);
8+
const dispatch = useDispatch();
9+
10+
return (
11+
<section>
12+
<h1>GLOBAL COUNTER: {globalState}</h1>
13+
<button onClick={() => dispatch(incrementCounter(globalState))}>
14+
Increment +
15+
</button>
16+
{" "}
17+
<button onClick={() => dispatch(decrementCounter(globalState))}>
18+
Decrement -
19+
</button>
20+
<br />
21+
<p>
22+
Try to reload this page or open a new tab or view this page another
23+
time.
24+
<br />
25+
You will see the same value everytime. Because the global state is
26+
persistent and saved in the localstorage
27+
</p>
28+
<header>
29+
<h1>An External API Call</h1>
30+
<p>
31+
just to show how next redux wrapper works with getStaticProps based
32+
Static Site Generation.
33+
</p>
34+
</header>
35+
{error && <div>There was an error.</div>}
36+
{!error && users && (
37+
<table>
38+
<thead>
39+
<tr>
40+
<th>Username</th>
41+
<th>Email</th>
42+
<th>Name</th>
43+
</tr>
44+
</thead>
45+
<tbody>
46+
{users.map((user, key) => (
47+
<tr key={key}>
48+
<td>{user.username}</td>
49+
<td>{user.email}</td>
50+
<td>{user.name}</td>
51+
</tr>
52+
))}
53+
</tbody>
54+
</table>
55+
)}
56+
</section>
57+
);
58+
};
59+
60+
const fetchData = async () =>
61+
await axios
62+
.get("https://jsonplaceholder.typicode.com/users")
63+
.then((res) => ({
64+
error: false,
65+
users: res.data,
66+
}))
67+
.catch(() => ({
68+
error: true,
69+
users: null,
70+
}));
71+
72+
export const getStaticProps = async () => {
73+
const data = await fetchData();
74+
75+
return {
76+
props: data,
77+
};
78+
};
79+
80+
export default Users;

pages/ssr/index.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React from "react";
2+
import axios from "axios";
3+
import { useSelector, useDispatch } from "react-redux";
4+
import { incrementCounter, decrementCounter } from "../../store/counter/action";
5+
6+
const fetchData = async () =>
7+
await axios
8+
.get("https://jsonplaceholder.typicode.com/users")
9+
.then((res) => ({
10+
error: false,
11+
users: res.data,
12+
}))
13+
.catch(() => ({
14+
error: true,
15+
users: null,
16+
}));
17+
18+
const Users = ({ users, error }) => {
19+
const globalState = useSelector((state) => state.counter.counter);
20+
const dispatch = useDispatch();
21+
return (
22+
<section>
23+
<header>
24+
<h1>GLOBAL COUNTER: {globalState}</h1>
25+
<button onClick={() => dispatch(incrementCounter(globalState))}>
26+
Increment +
27+
</button>
28+
{" "}
29+
<button onClick={() => dispatch(decrementCounter(globalState))}>
30+
Decrement -
31+
</button>
32+
<br />
33+
<strong>
34+
Try to reload this page or open a new tab or view this page another
35+
time.
36+
<br />
37+
You will see the same value everytime. Because the global state is
38+
persistent and saved in the localstorage
39+
</strong>
40+
<h1>List of users (An external api call with getServerSideProps)</h1>
41+
</header>
42+
{error && <div>There was an error.</div>}
43+
{!error && users && (
44+
<table>
45+
<thead>
46+
<tr>
47+
<th>Username</th>
48+
<th>Email</th>
49+
<th>Name</th>
50+
</tr>
51+
</thead>
52+
<tbody>
53+
{users.map((user, key) => (
54+
<tr key={key}>
55+
<td>{user.username}</td>
56+
<td>{user.email}</td>
57+
<td>{user.name}</td>
58+
</tr>
59+
))}
60+
</tbody>
61+
</table>
62+
)}
63+
</section>
64+
);
65+
};
66+
67+
export const getServerSideProps = async () => {
68+
const data = await fetchData();
69+
70+
return {
71+
props: data,
72+
};
73+
};
74+
75+
export default Users;

public/Homepage.gif

2.86 MB
Loading

0 commit comments

Comments
 (0)