Skip to content

Commit b82813c

Browse files
committed
Refactor class components to functions
1 parent 8b824e3 commit b82813c

File tree

4 files changed

+82
-96
lines changed

4 files changed

+82
-96
lines changed

src/components/ArticleForm.jsx

+44-46
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Component, Fragment } from "react";
1+
import React, { Fragment, useContext } from "react";
22
import { connect } from "react-redux";
33
import { Formik, Field, Form } from "formik";
44
import { format } from 'date-fns';
@@ -22,57 +22,55 @@ const validate = values => {
2222
return errors;
2323
}
2424

25-
export class ArticleForm extends Component {
26-
static contextType = SnackbarContext;
25+
export const ArticleForm = ({ article, title, createArticle, history }) => {
26+
const context = useContext(SnackbarContext)
2727

28-
submit = (values, { resetForm }) => {
28+
const submit = (values, { resetForm }) => {
2929
values.date = format(new Date(), 'MMMM d, yyyy H:mm:ss');
3030
values.id = Date.now();
31-
this.props.createArticle(values, this.props.history);
32-
this.context.showSnackbar('The article was published successfully', 'success');
31+
createArticle(values, history);
32+
context.showSnackbar('The article was published successfully', 'success');
3333
resetForm();
3434
}
3535

36-
render() {
37-
return (
38-
<Fragment>
39-
<h1 className="Article-form__title">{this.props.title || ''}</h1>
40-
<Formik
41-
initialValues={this.props.article || initialValues}
42-
onSubmit={this.submit}
43-
validate={validate}
44-
render={({ isSubmitting }) => (
45-
<Form className="Article-form">
46-
<Field
47-
name="title"
48-
placeholder="Title"
49-
component={TextField}
50-
/>
51-
<Field
52-
name="abstract"
53-
placeholder="Abstract"
54-
component={TextField}
55-
/>
56-
<Field
57-
name="text"
58-
placeholder="Text"
59-
rows={15}
60-
component={TextField}
61-
/>
62-
<button
63-
type="submit"
64-
disabled={isSubmitting}
65-
className="Article-form__button"
66-
>
67-
Submit
68-
</button>
69-
</Form>
70-
)}
71-
/>
72-
</Fragment>
73-
);
74-
}
75-
}
36+
return (
37+
<Fragment>
38+
<h1 className="Article-form__title">{title || ''}</h1>
39+
<Formik
40+
initialValues={article || initialValues}
41+
onSubmit={submit}
42+
validate={validate}
43+
render={({ isSubmitting }) => (
44+
<Form className="Article-form">
45+
<Field
46+
name="title"
47+
placeholder="Title"
48+
component={TextField}
49+
/>
50+
<Field
51+
name="abstract"
52+
placeholder="Abstract"
53+
component={TextField}
54+
/>
55+
<Field
56+
name="text"
57+
placeholder="Text"
58+
rows={15}
59+
component={TextField}
60+
/>
61+
<button
62+
type="submit"
63+
disabled={isSubmitting}
64+
className="Article-form__button"
65+
>
66+
Submit
67+
</button>
68+
</Form>
69+
)}
70+
/>
71+
</Fragment>
72+
);
73+
};
7674

7775
const mapDispatchToProps = {
7876
createArticle

src/components/ArticleList.jsx

+7-12
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
1-
import React, {Component} from 'react';
1+
import React from 'react';
22
import ArticleListItem from './ArticleListItem';
33
import withLoading from './utils/withLoading';
44

5-
export class ArticleList extends Component {
6-
listArticles = () => (
7-
Object.entries(this.props.articles).map(([key, val]) => {
5+
export const ArticleList = ({ articles }) => {
6+
const listArticles = () =>
7+
Object.entries(articles).map(([key, val]) => {
88
return <ArticleListItem key={key} article={val} />
99
})
10-
)
1110

12-
render() {
13-
return (
11+
return (
1412
<ul className="Article-list">
15-
{this.listArticles()}
13+
{listArticles()}
1614
</ul>
1715
)
18-
}
1916
}
2017

21-
ArticleList = withLoading(ArticleList)
22-
23-
export default ArticleList;
18+
export default withLoading(ArticleList);

src/components/ArticleListPage.jsx

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
import React, { Component } from 'react';
1+
import React, { useEffect } from 'react';
22
import { connect } from 'react-redux';
33
import { isLoading, getArticlesSelector } from '../selectors/articles';
44
import { fetchArticles } from '../actions/articles';
55
import { ArticleList } from './ArticleList';
66

7-
class ArticleListPage extends Component {
8-
componentDidMount() {
9-
this.props.fetchArticles();
10-
}
7+
const ArticleListPage = ({ articles, isLoading, fetchArticles }) => {
8+
useEffect(() => {
9+
fetchArticles()
10+
}, [fetchArticles]);
1111

12-
render() {
13-
const { articles, isLoading } = this.props;
14-
return (
15-
<ArticleList articles={articles} isLoading={isLoading} />
16-
)
17-
}
12+
return (
13+
<ArticleList articles={articles} isLoading={isLoading} />
14+
)
1815
}
1916

2017
const mapStateToProps = (state) => ({
+23-27
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,32 @@
1-
import React, { Component } from 'react';
1+
import React, { useState, useCallback, useMemo } from 'react';
22
import SnackbarContext from './SnackbarContext';
33
import Snackbar from './Snackbar';
44

5-
export class SnackbarProvider extends Component {
6-
showSnackbar = (message, status) => {
7-
this.setState({
8-
message,
9-
status,
10-
isOpen: true,
11-
});
12-
setTimeout(() => this.setState({ isOpen: false}), 3000);
13-
};
5+
export const SnackbarProvider = ({ children }) => {
6+
const [isOpen, setIsOpen] = useState(false)
7+
const [message, setMessage] = useState('')
8+
const [status, setStatus] = useState('success')
149

15-
state = {
16-
isOpen: false,
17-
message: '',
18-
status: 'success',
19-
showSnackbar: this.showSnackbar,
20-
};
10+
const showSnackbar = useCallback((message, status) => {
11+
setIsOpen(true)
12+
setMessage(message)
13+
setStatus(status)
14+
setTimeout(() => setIsOpen(false), 3000);
15+
}, []);
2116

22-
render() {
23-
const { children } = this.props;
17+
const value = useMemo(() => ({
18+
isOpen,
19+
message,
20+
status,
21+
showSnackbar,
22+
}), [isOpen, message, status, showSnackbar])
2423

25-
return (
26-
<SnackbarContext.Provider
27-
value={this.state}
28-
>
29-
<Snackbar />
30-
{children}
31-
</SnackbarContext.Provider>
32-
);
33-
}
24+
return (
25+
<SnackbarContext.Provider value={value}>
26+
<Snackbar />
27+
{children}
28+
</SnackbarContext.Provider>
29+
);
3430
}
3531

3632
export default SnackbarProvider;

0 commit comments

Comments
 (0)