hello i am not sure why i getting this error massage can some one correct my code i can not find key in my new post components
this is my newpost.js code
import React, { useContext } from 'react';
import { useHttpClient } from '../../hooks/useHttpClient';
import useForm from '../../hooks/useForm';
import { AuthContext } from '../../context/auth';
import { useHistory } from 'react-router-dom/cjs/react-router-dom.min';
import { newPostForm } from '../../utils/formConfig';
import { appendData, renderRepeatedSkeletons } from '../../utils';
import ErrorModal from '../../components/Modal/ErrorModal';
import SkeletonElement from '../../components/Skeleton/SkeletonElement';
const NewPost = () => {
const auth = useContext(AuthContext);
const history = useHistory();
const { currentUser } = auth;
const { isLoading, sendReq, error, clearError } = useHttpClient();
const { renderFormInputs, renderFormValues, isFormValid } =
useForm(newPostForm);
const formValues = renderFormValues();
const formInputs = renderFormInputs();
const postSubmitHandle = async (evt) => {
evt.preventDefault(); //otherwise, there will be a reload
const formData = appendData(formValues);
formData.append('author', currentUser.userId);
try {
await sendReq(
`${process.env.REACT_APP_BASE_URL}/posts`,
'POST',
formData,
{
Authorization: `Bearer ${currentUser.token}`,
}
);
history.push('/');
} catch (err) {}
};
return (
<>
<ErrorModal error={error} onClose={clearError} />
{isLoading ? (
renderRepeatedSkeletons(<SkeletonElement type='text' />, 20)
) : (
<div className='container-create-page'>
<form className='form form__create'>
<h2>Create a new post</h2>
{formInputs}
<button
onClick={postSubmitHandle}
className='btn'
disabled={!isFormValid()}
>
Submit <span>→</span>
</button>
</form>
</div>
)}
</>
);
};
export default NewPost;
and this is my useform.js code
import { useState, useCallback } from 'react';
//"signupForm" => "formObj" (name, email, password) => "form"
const useForm = (formObj) => {
const [form, setForm] = useState(formObj);
const renderFormInputs = () => {
//renders an [] of <Input> for all input fields
return Object.values(form).map((inputObj) => {
const { value, label, errorMessage, valid, renderInput } = inputObj;
return renderInput(
onInputChange,
value,
valid,
errorMessage,
label,
onCustomInputChange
);
});
};
const renderFormValues = () => {
let values = {};
Object.keys(form).forEach((inputObj) => {
values[inputObj] = form[inputObj].value;
});
return values;
};
const isInputFieldValid = useCallback(
(inputField) => {
for (const rule of inputField.validationRules) {
if (!rule.validate(inputField.value, form)) {
inputField.errorMessage = rule.message;
return false;
}
}
return true;
},
[form]
);
const onInputChange = useCallback(
(event) => {
const { name, value } = event.target;
let inputObj = { ...form[name], value };
const isValidInput = isInputFieldValid(inputObj);
if (isValidInput && !inputObj.valid) {
inputObj = { ...inputObj, valid: true };
} else if (!inputObj.touched && !isValidInput && inputObj.valid) {
inputObj = { ...inputObj, valid: false };
}
inputObj = { ...inputObj, touched: true };
setForm({ ...form, [name]: inputObj });
},
[form, isInputFieldValid]
);
const onCustomInputChange = useCallback(
(type, value, InputIsValid) => {
setForm({
...form,
[type]: { ...form[type], value, valid: InputIsValid },
});
},
[form]
);
const isFormValid = useCallback(
(customForm) => {
let isValid = true;
const arr = Object.values(customForm || form);
for (let i = 0; i < arr.length; i++) {
if (!arr[i].valid) {
isValid = false;
break;
}
}
return isValid;
},
[form]
);
return {
renderFormInputs,
renderFormValues,
isFormValid,
setForm,
};
};
export default useForm;
submit button does not work . it just a simple form with submit button and 4 input value and one image . if some one need more information . please ask in the comment section
index.js contain renderRepeatedSkeletons
export const checkInArray = (arr, elem) => {
return arr && arr.indexOf(elem) !== -1;
};
export const canModifyComment = (currentUserId, authorId) =>
currentUserId === authorId;
export const canReply = (currentUserId) => !!currentUserId;
export const isReplying = (activeComment, commentId) =>
activeComment &&
activeComment.type === 'replying' &&
activeComment.id === commentId;
export const isEditing = (activeComment, commentId) =>
activeComment &&
activeComment.type === 'editing' &&
activeComment.id === commentId;
export const readingTime = (body) => {
const wpm = 225;
const words = body.trim().split(/\s+/).length;
return `${Math.ceil(words / wpm)} min read`;
};
export const appendData = (data) => {
const formData = new FormData();
for (let [key, value] of Object.entries(data)) {
if (Array.isArray(value)) {
value = JSON.stringify(value);
}
formData.append(`${key}`, value);
}
return formData;
};
export const getReplies = (comments, commentId) => {
return (
comments &&
comments
.filter((comment) => comment && comment.parentId === commentId)
.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())
);
};
export const formatDate = (date) => {
const options = { year: 'numeric', month: 'short', day: 'numeric' };
const today = new Date(date);
return today.toLocaleDateString('en-US', options);
};
export const getRandomColor = () => {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
export const renderRepeatedSkeletons = (element, count) => {
let skeletons = [];
for (let i = 0; i < count; i++) {
skeletons.push(element);
}
return skeletons;
};
export const renderAlternateSkeletons = (elementOne, elementTwo, count) => {
let skeletons = [];
for (let i = 0; i < count; i++) {
if (i % 2 === 0) {
skeletons.push(elementOne);
} else {
skeletons.push(elementTwo);
}
}
return skeletons;
};