所以,我想重用表单组件来创建和编辑meetupForm数据。但是,我面临的问题是,我想在isEdit为true时将meetupForm数据传递给meetupForm组件,并使用该数据初始化输入字段,但它并不像预期的那样工作。
使用Input钩子处理输入
import { useReducer } from "react";
const inputStateReducer = (state, action) => {
if (action.type === "INPUT") {
console.log(action.value);
return { value: action.value, isTouched: state.isTouched };
}
if (action.type === "BLUR") {
return { value: state.value, isTouched: true };
}
if (action.type === "RESET") {
return { isTouched: false, value: "" };
}
return state;
};
const useInput = (validateValue, initalValue = "") => {
const [inputState, disptach] = useReducer(inputStateReducer, {
value: initalValue,
isTouched: false,
});
console.log("inputState.value:", inputState.value);
const valueIsValid = validateValue(inputState.value);
const hasError = !valueIsValid && inputState.isTouched;
const valueChangeHandler = (event) => {
disptach({ type: "INPUT", value: event.target.value });
};
const isTouchHandler = (event) => {
disptach({ type: "BLUR" });
};
const reset = () => {
disptach({ type: "RESET" });
};
return {
value: inputState.value,
isValid: valueIsValid,
hasError,
valueChangeHandler,
isTouchHandler,
reset,
};
};
export default useInput;
字符串
MeetupForm组件
import { FormLabel, TextField } from "@material-ui/core";
import { useState, useMemo, useEffect } from "react";
import useInput from "../../Hooks/useInput";
import imageIcon from "../../assests/imageicon.png";
import { useNavigate } from "react-router-dom";
const MeetUpForm = ({ url, isEdit = false, meetup }) => {
const [currentMeetup, setCurrentMeetup] = useState(meetup);
const [formError, setFormError] = useState(true);
const [eventImage, setEventImage] = useState(null);
const token = localStorage.getItem("token");
const [shouldUpload, setShouldUpload] = useState(null); // to decide if upload should be done or not
const [Date, setDate] = useState(null);
const navigate = useNavigate();
const [meetupError, setMeetupError] = useState(true);
const {
value: enteredName,
isValid: enteredNameIsValid,
hasError: nameInputError,
valueChangeHandler: nameChangeHandler,
isTouchHandler: nameBlurHandler,
reset: resetName,
} = useInput(
(value) => value.trim() !== "",
isEdit ? currentMeetup.name : ""
);
const {
value: enteredAddress,
isValid: enteredAddressIsValid,
hasError: addressInputError,
valueChangeHandler: addressChangeHandler,
isTouchHandler: addressBlurHandler,
reset: resetAddress,
} = useInput(
(value) => value.trim() !== "",
isEdit ? currentMeetup.address : ""
);
const {
value: enteredDescription,
isValid: enteredDescriptionIsValid,
hasError: discriptionInputError,
valueChangeHandler: descriptionChangeHandler,
isTouchHandler: descriptionBlurHandler,
reset: resetDescription,
} = useInput(
(value) => value.trim() !== "",
isEdit ? currentMeetup.description : ""
);
useEffect(() => {
setCurrentMeetup(meetup);
}, [meetup]);
console.log("currentMeetup.name:", currentMeetup.name);
const sumbitHandler = (event) => {
event.preventDefault();
console.log(enteredAddress, enteredDescription, enteredName);
if (
enteredDescriptionIsValid &&
enteredAddressIsValid &&
enteredNameIsValid
) {
setShouldUpload(true);
}
};
const formData = useMemo(() => {
const data = new FormData();
data.append("enteredAddress", enteredAddress);
data.append("enteredName", enteredName);
data.append("enteredDescription", enteredDescription);
data.append("image", eventImage);
data.append("date", Date);
return data;
}, [enteredAddress, enteredName, enteredDescription, eventImage, Date]);
useEffect(() => {
// post the data to backend
if (!shouldUpload) return;
const uploadData = async () => {
try {
const method = isEdit ? "PUT" : "POST";
const response = await fetch(isEdit ? `${url}/${meetup.id}` : url, {
method,
headers: {
Authorization: `Bearer ${token}`,
},
body: formData,
});
if (!response.ok) {
console.log("Error:", response.status);
setFormError(true);
}
const data = await response.json();
console.log(data.message);
if (data.message === "Meetup created successfully") {
navigate("/home");
}
} catch (error) {
console.log("Error file loading", error);
setMeetupError(true);
}
setShouldUpload(false);
};
uploadData();
}, [shouldUpload, formData, token, navigate, url, isEdit, meetup]);
return (
<div className="relative xl:3/5 flex flex-col justify-center max-xl:padding-x align-middle gap-5 max-container">
{!formError && (
<div className="border bg-red rounded-full">
<h1>Something went wrong try again</h1>
</div>
)}
{!meetupError && (
<div className="border bg-red rounded-full">
<h1>Meetup error</h1>
</div>
)}
<form
onSubmit={sumbitHandler}
className="relative xl:3/5 flex flex-col justify-center max-xl:padding-x align-middle gap-5 max-container"
>
<div className="flex flex-col">
<FormLabel className="items-start justify-start text-start font-palanquin pb-2">
Your Name
</FormLabel>
<TextField
type="text"
fullWidth
id="fullWidth"
value={enteredName}
color={nameInputError ? "primary" : "secondary"}
variant="outlined"
onChange={nameChangeHandler}
onBlur={nameBlurHandler}
></TextField>
</div>
<div className="flex flex-col">
<FormLabel className="items-start justify-start text-start font-palanquin pb-2">
Event Address
</FormLabel>
<TextField
type="text"
value={enteredAddress}
color={enteredAddressIsValid ? "primary" : "secondary"}
variant="outlined"
onChange={addressChangeHandler}
onBlur={addressBlurHandler}
></TextField>
</div>
<FormLabel>Event's Poster</FormLabel>
<div className="border-2 border-slate-700 rounded-md py-3 px-6">
<input
className="opacity-0 w-full z-5 mb-[-10px] "
type="file"
name="image"
id="image"
accept="/image*"
onChange={(e) => {
setEventImage(e.target.files[0]);
}}
alt="event poster image"
></input>
<img className="w-[40px] h-[40px] z-0" src={imageIcon} alt="hello" />
</div>
<FormLabel>Event's Date</FormLabel>
<TextField
type="date"
onChange={(e) => {
setDate(e.target.valueAsDate);
}}
variant="outlined"
></TextField>
<div className="flex flex-col">
<FormLabel className="items-start justify-start text-start font-palanquin pb-2">
Enter Event's Description
</FormLabel>
<textarea
className="my-3 pb-40 pt-2 px-3 border-2 border-slate-700 rounded-md focus:ring focus:ring-blue-200"
type="text"
value={enteredDescription}
color={enteredDescriptionIsValid ? "primary" : "secondary"}
onChange={descriptionChangeHandler}
onBlur={descriptionBlurHandler}
row={4}
cols={1}
></textarea>
</div>
<button
type="submit"
className=" bg-[#dc143c] text-center text-slate-200 rounded-full font-palanquin font-medium text-lg px-3 py-4 mx-8 "
>
Add Event
</button>
</form>
</div>
);
};
export default MeetUpForm;
型
请帮助我或建议我任何替代的方式这样做!
我尝试重用meetupform组件,但在通过自定义钩子预填充数据时遇到了问题
1条答案
按热度按时间agxfikkp1#
看起来你应该重构一下
useInput
钩子,这样当initialValue
参数改变时,它就可以重新初始化状态值。将reducer函数移到钩子体中,这样它就可以重置为初始值,并使用useEffect
钩子来分派重置操作。范例:
字符串
Demo
的数据