Skip to content

Commit 557ca31

Browse files
committed
convert class components to functions
1 parent 1d8e367 commit 557ca31

File tree

2 files changed

+134
-161
lines changed

2 files changed

+134
-161
lines changed

src/components/EmailSignup.js

Lines changed: 59 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,73 @@
1-
import React, { Fragment } from "react";
1+
import React, { useState } from "react";
22
import fetch from "unfetch";
33
import styled from "styled-components";
44
import analytics from "./../utils/analytics.js";
55

6-
class EmailSignup extends React.Component {
7-
constructor(props) {
8-
super(props);
9-
this.state = {
10-
subscribed: false,
11-
emailInputValue: ""
12-
};
13-
}
6+
const EmailSignup = () => {
7+
const [subscribed, setSubscribed] = useState(false);
8+
const [email, setEmail] = useState("");
149

15-
subscribe = async email => {
16-
this.setState({ subscribed: true });
10+
const subscribe = event => {
11+
event.preventDefault();
12+
if (!email) return;
1713
analytics.track("subscribe");
18-
19-
const response = await new Promise((resolve, reject) => {
20-
fetch("/api/subscribe", {
21-
method: "POST",
22-
headers: {
23-
"Content-Type": "application/json"
24-
},
25-
body: JSON.stringify({ email: email })
26-
})
27-
.then(r => r.json())
28-
.then(data => {
29-
resolve(data);
30-
});
14+
setSubscribed(true);
15+
return fetch("/api/subscribe", {
16+
method: "POST",
17+
headers: {
18+
"Content-Type": "application/json"
19+
},
20+
body: JSON.stringify({ email }).then(r => r.json())
3121
});
3222
};
33-
render() {
34-
const { subscribed } = this.state;
35-
return (
36-
<div className="card">
37-
<div className="card-content">
38-
{subscribed ? (
39-
<div className="has-text-centered has-text-weight-semibold">
40-
You are subscribed&nbsp;&nbsp;
41-
<span role="img" aria-label="party">
42-
🎉
23+
24+
return (
25+
<div className="card">
26+
<div className="card-content">
27+
{subscribed ? (
28+
<div className="has-text-centered has-text-weight-semibold">
29+
You are subscribed&nbsp;&nbsp;
30+
<span role="img" aria-label="party">
31+
🎉
32+
</span>
33+
</div>
34+
) : (
35+
<>
36+
<Title>
37+
<span role="img" aria-label="letter">
38+
📩
4339
</span>
44-
</div>
45-
) : (
46-
<Fragment>
47-
<Title>
48-
<span role="img" aria-label="letter">
49-
📩
50-
</span>
51-
&nbsp;&nbsp;Get new recipes in your inbox
52-
</Title>
53-
<form
54-
onSubmit={event => {
55-
event.preventDefault();
56-
const email = this.state.emailInputValue;
57-
if (email) {
58-
this.subscribe(email);
59-
}
60-
}}
61-
>
62-
<div className="field has-addons">
63-
<div className="control is-expanded">
64-
<input
65-
type="email"
66-
className="input"
67-
placeholder="Your Email"
68-
onChange={event => {
69-
this.setState({
70-
emailInputValue: event.target.value
71-
});
72-
}}
73-
/>
74-
</div>
75-
<div className="control">
76-
<button
77-
className="button is-primary has-text-weight-semibold"
78-
type="submit"
79-
>
80-
Subscribe
81-
</button>
82-
</div>
40+
&nbsp;&nbsp;Get new recipes in your inbox
41+
</Title>
42+
<form onSubmit={subscribe}>
43+
<div className="field has-addons">
44+
<div className="control is-expanded">
45+
<input
46+
type="email"
47+
className="input"
48+
placeholder="Your Email"
49+
onChange={event => {
50+
setEmail(event.target.value);
51+
}}
52+
/>
53+
</div>
54+
<div className="control">
55+
<button
56+
className="button is-primary has-text-weight-semibold"
57+
type="submit"
58+
>
59+
Subscribe
60+
</button>
8361
</div>
84-
</form>
85-
<Extra>Join 7,031 subscribers. No spam ever.</Extra>
86-
</Fragment>
87-
)}
88-
</div>
62+
</div>
63+
</form>
64+
<Extra>Join 7,031 subscribers. No spam ever.</Extra>
65+
</>
66+
)}
8967
</div>
90-
);
91-
}
92-
}
68+
</div>
69+
);
70+
};
9371

9472
const Title = styled("div").attrs({ className: "subtitle is-5" })`
9573
margin-bottom: 1.2rem;

src/templates/index.js

Lines changed: 75 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -5,95 +5,90 @@ import Layout from "../components/Layout";
55
import Search from "../components/Search";
66
import { PostTemplate } from "../templates/post.js";
77

8-
class IndexPage extends React.Component {
9-
state = { search: "" };
8+
const IndexPage = ({ pageContext }) => {
9+
//const [search, setSearch] = useState("");
10+
// const [searchMatches, setSearchMatches] = useState([]);
1011

11-
render() {
12-
const { pageContext } = this.props;
13-
const { group, index, first, last, pageCount } = pageContext;
14-
const previousUrl = index - 1 == 1 ? "/" : `/page/${index - 1}`;
15-
const nextUrl = "/page/" + (index + 1).toString();
16-
const { search } = this.state;
12+
const { group, index, first, last, pageCount } = pageContext;
13+
const previousUrl = index - 1 == 1 ? "/" : `/page/${index - 1}`;
14+
const nextUrl = "/page/" + (index + 1).toString();
1715

18-
// const filteredPosts = search ? searchPosts(posts, search) : posts;
16+
return (
17+
<Layout>
18+
{/*
19+
<Search
20+
value={search}
21+
onChange={value => setSearch({ search: value })}
22+
/>
23+
*/}
1924

20-
return (
21-
<Layout>
22-
{/*
23-
<Search
24-
value={this.search}
25-
onChange={value => this.setState({ search: value })}
25+
{group.map(({ node }) => (
26+
<PostTemplate
27+
key={node.id}
28+
content={node.html}
29+
frontmatter={node.frontmatter}
30+
slug={node.fields.slug}
2631
/>
27-
*/}
28-
29-
{group.map(({ node }) => (
30-
<PostTemplate
31-
key={node.id}
32-
content={node.html}
33-
frontmatter={node.frontmatter}
34-
slug={node.fields.slug}
35-
/>
36-
))}
32+
))}
3733

38-
<nav
39-
className="pagination is-centered"
40-
role="navigation"
41-
aria-label="pagination"
34+
<nav
35+
className="pagination is-centered"
36+
role="navigation"
37+
aria-label="pagination"
38+
style={{
39+
maxWidth: "600px",
40+
margin: "0 auto"
41+
}}
42+
>
43+
<Link
44+
className="pagination-previous"
45+
to={previousUrl}
46+
disabled={first}
4247
style={{
43-
maxWidth: "600px",
44-
margin: "0 auto"
48+
// Temp hack to prevent clicking
49+
// TODO: Render a link without a href instead
50+
pointerEvents: first ? "none" : "auto"
4551
}}
4652
>
47-
<Link
48-
className="pagination-previous"
49-
to={previousUrl}
50-
disabled={first}
51-
style={{
52-
// Temp hack to prevent clicking
53-
// TODO: Render a link without a href instead
54-
pointerEvents: first ? "none" : "auto"
55-
}}
56-
>
57-
Previous
58-
</Link>
59-
<Link
60-
className="pagination-next"
61-
to={nextUrl}
62-
disabled={last}
63-
style={{
64-
pointerEvents: last ? "none" : "auto"
65-
}}
66-
>
67-
Next Page
68-
</Link>
69-
<ul className="pagination-list">
70-
{Array(pageCount)
71-
.fill(null)
72-
.map((value, i) => {
73-
const pageNum = i + 1;
74-
const isCurrent = index === pageNum;
75-
const url = pageNum === 1 ? "/" : `/page/${pageNum}`;
53+
Previous
54+
</Link>
55+
<Link
56+
className="pagination-next"
57+
to={nextUrl}
58+
disabled={last}
59+
style={{
60+
pointerEvents: last ? "none" : "auto"
61+
}}
62+
>
63+
Next Page
64+
</Link>
65+
<ul className="pagination-list">
66+
{Array(pageCount)
67+
.fill(null)
68+
.map((value, i) => {
69+
const pageNum = i + 1;
70+
const isCurrent = index === pageNum;
71+
const url = pageNum === 1 ? "/" : `/page/${pageNum}`;
7672

77-
return (
78-
<li key={i}>
79-
<Link
80-
className={
81-
"pagination-link" + (isCurrent ? " is-current" : "")
82-
}
83-
to={url}
84-
>
85-
{pageNum}
86-
</Link>
87-
</li>
88-
);
89-
})}
90-
</ul>
91-
{/*<span>{` Page ${index} of ${pageCount}`}</span>*/}
92-
</nav>
93-
</Layout>
94-
);
95-
}
96-
}
73+
return (
74+
<li key={i}>
75+
<Link
76+
className={
77+
"pagination-link" + (isCurrent ? " is-current" : "")
78+
}
79+
to={url}
80+
>
81+
{pageNum}
82+
</Link>
83+
</li>
84+
);
85+
})}
86+
</ul>
87+
{/*<span>{` Page ${index} of ${pageCount}`}</span>*/}
88+
</nav>
89+
</Layout>
90+
);
91+
};
9792

9893
export default IndexPage;
9994

0 commit comments

Comments
 (0)