Skip to content

Commit

Permalink
refactor:refactor useCommentForm
Browse files Browse the repository at this point in the history
  • Loading branch information
ab3MN committed Nov 15, 2024
1 parent 41f6e1c commit cf4dd0d
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 99 deletions.
51 changes: 19 additions & 32 deletions src/components/Posts/NewCommentForm/NewCommentForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,8 @@ interface NewCommentFormProps {
export const NewCommentForm: React.FC<NewCommentFormProps> = ({
handleAddComment,
}) => {
const {
name,
nameError,
email,
emailError,
body,
bodyError,
isLoading,

handleChangeName,
handleChangeEmail,
handleChangeBody,
reset,
handleSubmit,
} = useCommentForm(handleAddComment);
const { isLoading, state, reset, handleSubmit, handleChange } =
useCommentForm(handleAddComment);

return (
<form data-cy="NewCommentForm" onSubmit={handleSubmit}>
Expand All @@ -35,18 +22,18 @@ export const NewCommentForm: React.FC<NewCommentFormProps> = ({
<input
type="text"
name="name"
value={name}
value={state.name.value}
onChange={handleChange}
id="comment-author-name"
placeholder="Name Surname"
className={cn('input', { 'is-danger': nameError })}
onChange={handleChangeName}
className={cn('input', { 'is-danger': state.name.error })}
/>

<span className="icon is-small is-left">
<i className="fas fa-user" />
</span>

{nameError && (
{state.name.error && (
<span
className="icon is-small is-right has-text-danger"
data-cy="ErrorIcon"
Expand All @@ -56,9 +43,9 @@ export const NewCommentForm: React.FC<NewCommentFormProps> = ({
)}
</div>

{nameError && (
{state.name.error && (
<p className="help is-danger" data-cy="ErrorMessage">
{nameError}
{state.name.error}
</p>
)}
</div>
Expand All @@ -72,18 +59,18 @@ export const NewCommentForm: React.FC<NewCommentFormProps> = ({
<input
type="text"
name="email"
value={email}
value={state.email.value}
onChange={handleChange}
id="comment-author-email"
placeholder="[email protected]"
className={cn('input', { 'is-danger': emailError })}
onChange={handleChangeEmail}
className={cn('input', { 'is-danger': state.email.error })}
/>

<span className="icon is-small is-left">
<i className="fas fa-envelope" />
</span>

{emailError && (
{state.email.error && (
<span
className="icon is-small is-right has-text-danger"
data-cy="ErrorIcon"
Expand All @@ -93,9 +80,9 @@ export const NewCommentForm: React.FC<NewCommentFormProps> = ({
)}
</div>

{emailError && (
{state.email.error && (
<p className="help is-danger" data-cy="ErrorMessage">
{emailError}
{state.email.error}
</p>
)}
</div>
Expand All @@ -109,16 +96,16 @@ export const NewCommentForm: React.FC<NewCommentFormProps> = ({
<textarea
id="comment-body"
name="body"
value={body}
value={state.body.value}
onChange={handleChange}
placeholder="Type comment here"
className={cn('textarea', { 'is-danger': bodyError })}
onChange={handleChangeBody}
className={cn('textarea', { 'is-danger': state.body.error })}
/>
</div>

{bodyError && (
{state.body.error && (
<p className="help is-danger" data-cy="ErrorMessage">
{bodyError}
{state.body.error}
</p>
)}
</div>
Expand Down
118 changes: 51 additions & 67 deletions src/hooks/useCommentForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,109 +8,93 @@ import {
import { PostsContext } from '../context/PostContext';
import { Comment } from '../types/Comment';

const initialState = {
name: { value: '', error: '' },
email: { value: '', error: '' },
body: { value: '', error: '' },
};

export const useCommentForm = (
handleAddComment: (comment: Omit<Comment, 'id'>) => Promise<void>,
) => {
const { selectedPost } = useContext(PostsContext);

const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [body, setBody] = useState('');
const [nameError, setNameError] = useState('');
const [emailError, setEmailError] = useState('');
const [bodyError, setBodyError] = useState('');
const [isLoading, setLoading] = useState(false);
const [state, setState] = useState(initialState);

const showErrors = () => {
if (!name) {
setNameError('Name is required');
}
if (!email) {
setEmailError('Email is required');
}
if (!body) {
setBodyError('Enter some text');
}
const setStateByInputName = (inputName = '', value = '', error = '') => {
setState(prevState => ({
...prevState,
[inputName]: {
error,
value,
},
}));
};

const reset = () => {
setNameError('');
setEmailError('');
setBodyError('');
setName('');
setEmail('');
setBody('');
};
const [isLoading, setLoading] = useState(false);

const handleChangeName = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
const handleChange = useCallback(
(event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { value, name } = event.target;

if (nameError) {
setNameError('');
}
setStateByInputName(name, value, '');
},
[nameError],
[state],

Check warning on line 42 in src/hooks/useCommentForm.ts

View workflow job for this annotation

GitHub Actions / run_linter (20.x)

React Hook useCallback has an unnecessary dependency: 'state'. Either exclude it or remove the dependency array
);

const handleChangeEmail = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
setEmail(event.target.value);
const showErrors = () => {
const { name, email, body } = state;

if (emailError) {
setEmailError('');
}
},
[emailError],
);
if (!name.value) {
setStateByInputName('name', '', 'Name is required');
}

const handleChangeBody = useCallback(
(event: ChangeEvent<HTMLTextAreaElement>) => {
setBody(event.target.value);
if (!email.value) {
setStateByInputName('email', '', 'Email is required');
}

if (bodyError) {
setBodyError('');
}
},
[bodyError],
);
if (!body.value) {
setStateByInputName('body', '', 'Enter some text');
}
};

const reset = () => {
setState(initialState);
};

const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
const { name, email, body } = state;

event.preventDefault();

if (!(name && email && body)) {
if (!(name.value && email.value && body.value)) {
showErrors();

return;
}

setLoading(true);

handleAddComment({
name,
email,
body,
const comment = {
name: name.value,
email: email.value,
body: body.value,
postId: selectedPost!.id,
}).then(() => {
setBody('');
};

handleAddComment(comment).then(() => {
setStateByInputName('body', '', '');

setLoading(false);
});
};

return {
name,
nameError,
email,
emailError,
body,
bodyError,
isLoading,
state,

handleChangeName,
handleChangeEmail,
handleChangeBody,
handleChange,
reset,
showErrors,
handleSubmit,
};
};

0 comments on commit cf4dd0d

Please sign in to comment.