After editing data, redux cannot read id - reactjs

i have a problem.
I use a form to edit my data, then when i want to see edited data, i get an ×
TypeError: Cannot read properties of undefined (reading 'id')
Pointing at my
{users &&
users.map((user) => {
return (
<div key={user.id}>
<Link to={`users/${user.id}`}> {user.name} </Link>
</div>
);
})}
Which is used to display data.
After refreshing the site (F5) it works, so i assume that the redux has problem with reading edited data for the first time, altough it do work with adding new data. anyone know what i can do?
My UserEditForm:
const UserEditForm = () => {
let { id } = useParams();
const { user } = useSelector((state) => state.user);
const [state, setState] = useState({
name: "",
birthday: "",
img: "",
});
const [error, setError] = useState("");
console.log(id);
let history = useHistory();
let dispatch = useDispatch();
const { name, birthday, img } = state;
useEffect(() => {
dispatch(getSingleUser(id));
}, []);
useEffect(() => {
if (user) {
setState({ ...user });
}
}, [user]);
const handleInputChange = (e) => {
let { name, value } = e.target;
setState({ ...state, [name]: value });
};
const handleSubmit = (e) => {
dispatch(updateUser(state, id));
history.push("/");
setError("");
};
return (
<div>
<Button
style={{ width: "100px", marginTop: "20px" }}
variant="contained"
color="secondary"
onClick={() => history.push("/")}
>
Go Back
</Button>
<h2>Edit User</h2>
{error && <h3 style={{ color: "red" }}>{error}</h3>}
<form noValidate autoComplete="off" onSubmit={handleSubmit}>
<TextField
id="standard-basic"
label="Name"
value={name || ""}
name="name"
type="text"
onChange={handleInputChange}
/>
<br />
<TextField
id="standard-basic"
label="birthday"
name="birthday"
value={birthday || ""}
type="birthday"
onChange={handleInputChange}
/>
<br />
<TextField
id="standard-basic"
label="img"
value={img || ""}
name="img"
type="number"
onChange={handleInputChange}
/>
<Button
style={{ width: "100px" }}
variant="contained"
color="primary"
type="submit"
onChange={handleInputChange}
>
Update
</Button>
</form>
</div>
);
};
export default UserEditForm;
My UserList component:
const UserList = ({ users, history }) => {
const dispatch = useDispatch();
const fetchUsers = async () => {
const response = await axios
.get("http://localhost:3000/characters")
.catch((err) => {
console.log("Err: ", err);
});
dispatch(setUsers(response.data));
};
useEffect(() => {
fetchUsers();
}, []);
console.log(users);
return (
<div>
<button onClick={() => history.goBack()}>...back</button>
<li>
<Link to="/user/add">Add Users</Link>
</li>
{users &&
users.map((user) => {
return (
<div key={user.id}>
<Link to={`users/${user.id}`}> {user.name} </Link>
</div>
);
})}
</div>
);
};
const mapStateToProps = (state) => {
return {
users: state.allUsers.users,
};
};
export default connect(mapStateToProps, null)(UserList);

Related

strapi and react form not adding data to the admin

previous issue
building a rating app using strapi and react throws errors is solved.
But, the records are not getting added to the admin.
can anyone help on this?
This is the code to add and read reviews from strapi admin,
function App() {
const stars = Array(5).fill(0);
const [currentValue, setCurrentValue] = React.useState(0);
const [hoverValue, setHoverValue] = React.useState(undefined);
const handleClick = (value) => {
setCurrentValue(value);
};
const handleMouseOver = (value) => {
setHoverValue(value);
};
const [review, setReview] = useState({});
const [reviews, setReviews] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await api.readReviews();
//console.log(result.data);
setReviews(result.data.data);
};
fetchData();
}, []);
const createReview = async () => {
try {
//console.log(review);
const data = await api.createReview(review);
setReview([...reviews, data]);
} catch (error) {
//console.log(error);
}
};
let [reviewCount, setreviewCount] = useState([]);
const setCountFxn = (no) => {
setReview(no);
};
return (
<>
<form>
<div style={styles.container}>
<h2>RATE OUR SERVICE</h2>
<div style={styles.stars}>
{stars.map((_, index) => {
return (
<FaStar
key={index}
size={24}
style={{
marginRight: 10,
cursor: 'pointer',
}}
color={(hoverValue || currentValue) > index ? colors.orange : colors.grey}
onClick={() => {
setReview({ ...review, Rating: index + 1 });
}}
onMouseOver={() => handleMouseOver(index + 1)}
/>
);
})}
</div>
<div>
<input
type='text'
placeholder='input your name'
required
style={styles.input}
value={review.Name}
onChange={(e) => setReview({ ...review, Name: e.target.value })}
/>
</div>
<textarea
placeholder="what's your feedback"
required
style={styles.textarea}
value={review.review}
onChange={(e) => setReview({ ...review, review: e.target.value })}
/>
<button type='submit' style={styles.button} className='btn btn-primary' onClick={createReview}>
submit
</button>
</div>
</form>
<section id='reviews'>
<div className='reviews-heading'>
<span>REVIEWS FROM CUSTOMERS</span>
</div>
<div className='container'>
<div className='row'>
{reviews.map((review, i) => (
<div key={review.id} className='col-md-6'>
<div className='reviews-box'>
<div className='box-top'>
<div className='profile'>
<div className='name-user'>
<strong>{review.attributes.Title}</strong>
</div>
</div>
<div style={styles.stars}>
{Array.from({ length: review.attributes.Rating }).map((i) => (
<FaStar key={i} size={18} color={colors.orange} />
))}
</div>
</div>
<div className='client-comment'>{review.attributes.Body}</div>
</div>
</div>
))}
</div>
</div>
</section>
</>
);
}
export default App;
The form gets submitted and reloads after submit, but the record does not get added to strapi admin. I've set the roles of the data to public.
thanks
Nabi
You need a very specific structure to create a new entry with strapi. I assume your payload looks like this:
{
name: 'xyz',
rating: 5
}
Correct would be:
{
data: {
name: 'xyz',
rating: 5
}
}
Strapi Docs - Creating an entry
Ive figured it out!
The values of the form were named wrong. "Name" should be "Title" and "review" should be "Body". It now adds the data to the strapi admin.

How i can implement redux saga concept in login page react

Here how can i implement this login page using Redux saga concept. I also attached my codesandbox link below. Please provide any ideas to implement using redux saga concept.
For what purpose we mainly use redux saga concepts in react. Please provide any articles for learning redux saga.
https://codesandbox.io/s/inspiring-rain-olm7wx?file=/src/components/Login.jsx
import React from "react";
import { connect } from "react-redux";
import { loginAction } from "../actions/loginAction";
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";
const emailValidator = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const passwordValidator = /(?=.*[a-z])/;
function Login(props) {
let navigate = useNavigate();
const isLogin = useSelector((state) => state.login.isLogin);
useEffect(() => {
if (isLogin) {
navigate("/");
}
}, [isLogin]);
const [state, setState] = useState({
email: "",
password: "",
emailAddressError: "",
passwordError: "",
isLogin: false,
isFormSubmitted: false
});
const handleChange = (event) => {
const { name, value } = event.target;
setState((prev) => ({ ...prev, [name]: value }));
return;
};
const handleBlur = (event) => {
const { name } = event.target;
validateField(name);
return;
};
const handleSubmit = (event) => {
event.preventDefault();
var data = {
email: state.email,
password: state.password
};
let formFileds = ["email", "password"];
let isValid = true;
formFileds.forEach((field) => {
isValid = validateField(field) && isValid;
});
if (isValid) {
setState((prev) => ({ ...prev, isFormSubmitted: true }));
const dispatch = props.dispatch;
dispatch(loginAction.login(data));
} else setState((prev) => ({ ...prev, isFormSubmitted: false }));
return state.isFormSubmitted;
};
const validateField = (name) => {
let isValid = false;
if (name === "email") isValid = validateemail();
else if (name === "password") isValid = validatePassword();
return isValid;
};
const validateemail = () => {
let emailAddressError = "";
const value = state.email;
if (value.trim() === "") emailAddressError = "Email Address is required";
else if (!emailValidator.test(value))
emailAddressError = "Email is not valid";
setState((prev) => ({ ...prev, emailAddressError }));
return emailAddressError === "";
};
const validatePassword = () => {
let passwordError = "";
const value = state.password;
if (value.trim() === "") passwordError = "Password is required";
else if (!passwordValidator.test(value))
passwordError = "Password contains small character only";
setState((prev) => ({ ...prev, passwordError }));
return passwordError === "";
};
return (
<div>
<div>
<div class="no-gutters row" style={{ height: "100vh" }}>
<div class="d-flex flex-column justify-content-center align-items-center h-100 col-12 col-md-6">
<div class="container">
<div class="d-flex justify-content-center row">
<div class="col-auto col-lg-8">
<h5 class="fw-bold mb-5">Login</h5>
<form className="form" onSubmit={handleSubmit}>
<div class="form-group">
<label class="form-label">
<b>Email</b>
</label>{" "}
<span style={{ color: "red" }}> *</span>
<input
type="text"
class="form-control"
label="email"
name="email"
value={state.email}
onChange={handleChange}
placeholder="email"
onBlur={handleBlur}
autoComplete="off"
/>
{state.emailAddressError && (
<div className="errorMsg" style={{ color: "red" }}>
{state.emailAddressError}
</div>
)}
</div>
<div class="Login_formGroup__3wtgQ form-group">
<label class="form-label">
<b>Password</b>
</label>{" "}
<span style={{ color: "red" }}> *</span>
<input
type="password"
class="form-control"
variant="outlined"
id="outlined-basic"
label="password"
name="password"
value={state.password}
onChange={handleChange}
placeholder="password"
onBlur={handleBlur}
autoComplete="off"
/>
{state.passwordError && (
<div className="errorMsg" style={{ color: "red" }}>
{state.passwordError}
</div>
)}
</div>
<div class="d-flex justify-content-between align-items-center mt-5">
<button
class="btn "
style={{ backgroundColor: "#bd744c", color: "white" }}
>
<b>LOGIN</b>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
const mapStateToProps = (state) => {
return {
token: state.login.token
};
};
export default connect(mapStateToProps)(Login);

Why is my check complete button is not working

I wanna make the function that whenever i click on the complete button, the complete state will turn true and there will be a line through in my todo. However, my function is not working and i don't know why? can anyone help me? Thank you so much!
import React, { useState } from "react";
function App() {
const [value, setValue] = useState("");
const [todos, setTodos] = useState([]);
// you can use the submit itself, no need for an extra addTodo function
const handleSubmit = (e) => {
e.preventDefault();
setTodos([...todos, { value, id: Date.now() }]);
setValue("");
};
const handleDelete = (id) => {
setTodos((todos) => todos.filter((todo) => todo.id !== id));
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
onChange={(e) => setValue(e.target.value)}
type="text"
placeholder="add todo"
/>
<button type="submit">Add</button>
</form>
{todos.map((todo) => (
<div key={todo.id}>
<h3 complete ? "line-through" : "">{todo.value}</h3>
<button onClick={() => handleDelete(todo.id)}>X</button>
<button onClick={()=>setComplete(!complete)}>complete</button>
</div>
))}
</div>
);
}
export default App;
Sandbox link: https://codesandbox.io/s/stoic-mendeleev-6fetl?file=/src/App.js
complete state missing
h3 add style={{ textDecoration: complete ? "line-through" : "" }}
import React, { useState } from "react";
function App() {
const [value, setValue] = useState("");
const [todos, setTodos] = useState([]);
const [complete, setComplete] = useState(false);
// you can use the submit itself, no need for an extra addTodo function
const handleSubmit = (e) => {
e.preventDefault();
setTodos([...todos, { value, id: Date.now() }]);
setValue("");
};
const handleDelete = (id) => {
setTodos((todos) => todos.filter((todo) => todo.id !== id));
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
onChange={(e) => setValue(e.target.value)}
type="text"
placeholder="add todo"
value={value}
/>
<button type="submit">Add</button>
</form>
{todos.map((todo) => (
<div key={todo.id}>
<h3 style={{ textDecoration: complete ? "line-through" : "" }}>
{todo.value}
</h3>
<button onClick={() => handleDelete(todo.id)}>X</button>
<button onClick={() => setComplete((perv) => !perv)}>complete</button>
</div>
))}
</div>
);
}
export default App;
Try this
import React, { useState } from "react";
function App() {
const [value, setValue] = useState("");
const [todos, setTodos] = useState([]);
const [complete, setComplete] = useState({});
// you can use the submit itself, no need for an extra addTodo function
const handleSubmit = (e) => {
e.preventDefault();
const id = Date.now();
setTodos([...todos, { value, id }]);
setComplete({ ...complete, [id]: false });
setValue("");
};
const handleDelete = (id) => {
setTodos((todos) => todos.filter((todo) => todo.id !== id));
};
console.log(complete);
return (
<div>
<form onSubmit={handleSubmit}>
<input
onChange={(e) => setValue(e.target.value)}
type="text"
placeholder="add todo"
value={value}
/>
<button type="submit">Add</button>
</form>
{todos.map((todo) => (
<div key={todo.id}>
<h3 className={complete[todo.id] ? "line-through" : ""}>
{todo.value}
</h3>
<button onClick={() => handleDelete(todo.id)}>X</button>
<button
onClick={() =>
setComplete({ ...complete, [todo.id]: !complete[todo.id] })
}
>
complete
</button>
</div>
))}
</div>
);
}
export default App;
*Note you will need to specify styling for your line-through class to see the strike through
I have updated the codesandbox. you can have look on the codesandbox.
https://codesandbox.io/s/compassionate-frost-8255y
Try below code.
You need to create setComplete menthod.
import React, { useState } from "react";
function App() {
const [value, setValue] = useState("");
const [todos, setTodos] = useState([]);
// you can use the submit itself, no need for an extra addTodo function
const handleSubmit = (e) => {
e.preventDefault();
setTodos([...todos, { value, id: Date.now(), complete: false }]);
setValue("");
};
const handleDelete = (id) => {
setTodos((todos) => todos.filter((todo) => todo.id !== id));
};
const handleComplete = (id) => {
let compTodo = todos.filter((todo) => todo.id === id);
compTodo[0].complete = true;
let allTodo = todos.filter((todo) => todo.id !== id);
setTodos([...allTodo, compTodo[0]]);
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
onChange={(e) => setValue(e.target.value)}
type="text"
placeholder="add todo"
value={value}
/>
<button type="submit">Add</button>
</form>
{todos.map((todo) => {
return (
<div key={todo.id}>
<h3
style={{
textDecoration: todo.complete ? "line-through" : "none"
}}
>
{todo.value}
</h3>
<button onClick={() => handleDelete(todo.id)}>X</button>
<button onClick={() => handleComplete(todo.id)}>complete</button>
</div>
);
})}
</div>
);
}
export default App;

How can I put a counter up in my form and add data in the databases using reactjs ,formik and axios

I ‘m new in react js
I put a counter up in my form I have problem to put the result of counter with the form result in the databases
I use for my Api mongodb and spring boot
Count up function
export default function Index(props) {
/* Server State Handling */
const [count, setCount] = useState(0);
const [delay, setDelay] = useState(1000);
useInterval(() => setCount((c) => c + 1), delay);
useEffect(() => {
if (delay === null) alert(`Count ${count}`);
}, [count, delay]);
function useInterval(callback, delay) {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
let id;
if (delay) {
id = setInterval(savedCallback.current, delay);
}
return () => clearInterval(id);
}, [delay]);
}
const [serverState, setServerState] = useState();
const handleServerResponse = (ok, msg) => {
setServerState({ok, msg});
};
Function of submitting data
const handleOnSubmit = (values, actions) => {
axios.post( "/consultations", values,
)
.then(response => {
props.history.push("/listcons");
actions.setSubmitting(false);
actions.resetForm();
handleServerResponse(true, "Thanks!");
alert("Consultation enregister avec succer");
})
.catch(error => {
actions.setSubmitting(false);
handleServerResponse(false, error.response.data.error);
});
My form with the counter up
I have problem here when I submitted my form in my databases the count value is always 0 (the initial value) how can I resolve this problem what is the problem of my code
return (
<div className="container ">
<div className="card-body bg-white">
<Formik
initialValues={{count:0,titre: ""}}
onSubmit={handleOnSubmit}
validationSchema={formSchema}
>
{({ isSubmitting }) => (
<Form id="fs-frm" noValidate >
<div style={{textAlign: 'center'}}>
<h3>Count</h3>
<h2> {count}</h2>
</div>
<div className="form-group" >
<label htmlFor="titre">Titre</label>
<Field id="titre" name="titre" className="form-control" />
<ErrorMessage name="titre" className="errorMsg" component="p" />
</div>
<Card.Footer style={{ "textAlign": "right" }}>
<button type="submit" className="btn btn-primary" disabled={isSubmitting}>
Submit
</button>
</Card.Footer>
{serverState && (
<p className={!serverState.ok ? "errorMsg" : ""}>
{serverState.msg}
</p>
)}
</Form>
)}
</Formik>
</div>
</div>
);
};

How to use react-dropzone with react-hook-form?

How to use react-dropzone with react-hook-form so that the form returns proper file - not just file name?
Here is a work from a react-hook-form Github discussion:
export const DropzoneField = ({
name,
multiple,
...rest
}) => {
const { control } = useFormContext()
return (
<Controller
render={({ onChange }) => (
<Dropzone
multiple={multiple}
onChange={e =>
onChange(multiple ? e.target.files : e.target.files[0])
}
{...rest}
/>
)}
name={name}
control={control}
defaultValue=''
/>
)
}
const Dropzone = ({
multiple,
onChange,
...rest
}) => {
const {
getRootProps,
getInputProps,
} = useDropzone({
multiple,
...rest,
})
return (
<div {...getRootProps()}>
<input {...getInputProps({ onChange })} />
</div>
)
}
You should check out Controller API as it was made to make integration with external controlled input easier. There are quite a few examples therein as well.
i did this way #Bill
const FileUpload = (props) => {
const {
control,
label,
labelClassName,
name,
isRequired,
rules,
error,
multiple,
maxFiles,
setValue,
accept,
maxSize,
setError,
clearErrors,
formGroupClassName,
watch,
} = props;
const [files, setFiles] = useState(watch(name));
const onDrop = useCallback(
(acceptedFiles, rejectedFiles) => {
if (rejectedFiles && rejectedFiles.length > 0) {
setValue(name, []);
setFiles([]);
setError(name, {
type: 'manual',
message: rejectedFiles && rejectedFiles[0].errors[0].message,
});
} else {
setFiles(
acceptedFiles.map((file) =>
Object.assign(file, {
preview: URL.createObjectURL(file),
}),
),
);
clearErrors(name);
acceptedFiles.forEach((file) => {
const reader = new FileReader();
reader.onabort = () => toastError('File reading was aborted');
reader.onerror = () => toastError('file reading has failed');
reader.readAsDataURL(file);
reader.onloadend = () => {
setValue(name, file, { shouldValidate: true });
};
});
}
},
[name, setValue, setError, clearErrors],
);
const deleteFile = (e, file) => {
e.preventDefault();
const newFiles = [...files];
newFiles.splice(newFiles.indexOf(file), 1);
if (newFiles.length > 0) {
setFiles(newFiles);
} else {
setFiles(null);
setValue(name, null);
}
};
const thumbs =
files &&
files !== null &&
files.map((file) => {
const ext = file.name && file.name.substr(file.name.lastIndexOf('.') + 1);
return ext === 'pdf' ? (
<ul key={file.name} className="mt-2">
<li>{file.name}</li>
</ul>
) : (
<div className="thumb position-relative" key={file.name}>
<img src={file.preview ? file.preview : file} alt={file.name} />
<Button
className="trash-icon"
color="danger"
size="sm"
onClick={(e) => deleteFile(e, file)}
>
<FontAwesomeIcon icon={faTrashAlt} size="sm" />
</Button>
</div>
);
});
useEffect(() => {
if (
watch(name) !== '' &&
typeof watch(name) === 'string' &&
watch(name).startsWith('/')
) {
setFiles([
{
preview: getFileStorageBaseUrl() + watch(name),
name: watch(name)
.substr(watch(name).lastIndexOf('/') + 1)
.substr(0, watch(name).lastIndexOf('/')),
},
]);
}
}, [watch, name]);
useEffect(
() => () => {
if (files && files.length > 0) {
files.forEach((file) => URL.revokeObjectURL(file.preview));
}
},
[files],
);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
maxFiles: multiple ? maxFiles : 0,
accept,
onDrop,
minSize: 0,
maxSize,
multiple,
});
return (
<div className={formGroupClassName || 'file-input my-2 form-group'}>
{label && (
<label className={labelClassName} htmlFor={name}>
{label}
{isRequired && <span style={{ color: 'red' }}> * </span>}
</label>
)}
<Controller
control={control}
name={name}
rules={rules}
render={(controllerProps) => (
<div
{...getRootProps({
className: 'dropzone w-100 fs-20 d-flex align-items-center',
})}
{...controllerProps}
>
<input {...getInputProps()} />
<FontAwesomeIcon
icon={faCloudUploadAlt}
size="sm"
className="mr-1"
/>
{isDragActive ? (
<span className="fs-16">Drop the files here ... </span>
) : (
<span className="fs-16">Select files </span>
)}
</div>
)}
/>
<aside className="thumbs-container">{thumbs}</aside>
{error && <p className="form-error mb-0">{error.message}</p>}
</div>
);
};
here is the solution with v7
const DropzoneField = ({
name,
control,
...rest
}: {
name: string;
control: Control<FieldValues>;
}) => {
// const { control } = useFormContext();
return (
<Controller
render={({ field: { onChange } }) => (
<Dropzone onChange={(e: any) => onChange(e.target.files[0])} {...rest} />
)}
name={name}
control={control}
defaultValue=""
/>
);
};
const Dropzone = ({ onChange, ...rest }: { onChange: (...event: any[]) => void }) => {
const onDrop = useCallback((acceptedFiles) => {
// Do something with the files
console.log({ acceptedFiles });
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
return (
<div {...getRootProps()}>
<input {...getInputProps({ onChange })} />
{isDragActive ? (
<p>Drop the files here ...</p>
) : (
<p>Drag 'n' drop some files here, or click to select files</p>
)}
</div>
);
};
I got it working properly including with both drop and click to add a file using the following code:
FileInput.js
import React, { useCallback, useEffect } from "react"
import { useDropzone } from "react-dropzone"
import { useFormContext } from "react-hook-form"
const FileInput = props => {
const { name, label = name } = props
const { register, unregister, setValue, watch } = useFormContext()
const files = watch(name)
const onDrop = useCallback(
droppedFiles => {
setValue(name, droppedFiles, { shouldValidate: true })
},
[setValue, name]
)
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: props.accept,
})
useEffect(() => {
register(name)
return () => {
unregister(name)
}
}, [register, unregister, name])
return (
<>
<label className=" " htmlFor={name}>
{label}
</label>
<div
{...getRootProps()}
type="file"
role="button"
aria-label="File Upload"
id={name}
>
<input {...props} {...getInputProps()} />
<div
style={{ width: "500px", border: "black solid 2px" }}
className={" " + (isDragActive ? " " : " ")}
>
<p className=" ">Drop the files here ...</p>
{!!files?.length && (
<div className=" ">
{files.map(file => {
return (
<div key={file.name}>
<img
src={URL.createObjectURL(file)}
alt={file.name}
style={{
height: "200px",
}}
/>
</div>
)
})}
</div>
)}
</div>
</div>
</>
)
}
export default FileInput
Form
import React from "react"
import { FormProvider, useForm } from "react-hook-form"
import FileInput from "./FileInput"
const Form = () => {
const methods = useForm({
mode: "onBlur",
})
const onSubmit = methods.handleSubmit(values => {
console.log("values", values)
})
return (
<FormProvider {...methods}>
<form onSubmit={onSubmit}>
<div className="">
<FileInput
accept="image/png, image/jpg, image/jpeg, image/gif"
name="file alt text"
label="File Upload"
/>
</div>
</form>
</FormProvider>
)
}
export default Form

Resources