React setting an entire state with an object - reactjs

I have a state of FormData
const [FormData, setFormData] = useState({}) as any;
I have an object cir which contains many keys.
How to set the FormData with cir initially and later update with form?
Object.keys(cir).forEach((key) => {
setFormData({ ...FormData, [key]: cir.key });
console.log(key, cir[key]);
});
const [FormData, setFormData] = useState({}) as any;
const [Test, setTest] = useState<object>();
// States-------States-------States-------States-------States-------States-------States-------States-------
// This is Working
const onChange = (e: any) => {
const { name, value } = e.target;
setFormData({ ...FormData, [name]: value });
};
// useEffect----------useEffect----------useEffect----------useEffect----------useEffect----------useEffect
useEffect(() => {
if (!user) {
navigate("/");
}
dispatch(getCIR(params._id));
console.log(FormData);
}, []);
// useEffect----------useEffect----------useEffect----------useEffect----------useEffect----------useEffect
const setInitialFormData = () => {
Object.keys(cir).forEach((key : string) => {
// This is not working. Why?????
setFormData({ ...FormData, key: cir[key] });
});
}
if (isSuccess) {
setInitialFormData();
}
This is not working.

Related

displaying a sucess message using email.js

I'm wondering how I can display a "message sent successfully" message after the user has submitted the form?
Any help would be greatly appreciated. Right now the message is sent but there is no success message displayed.
export const Contact = (props) => {
const [{ name, email, message }, setState] = useState(initialState)
const handleChange = (e) => {
const { name, value } = e.target
setState((prevState) => ({ ...prevState, [name]: value }))
}
const clearState = () => setState({ ...initialState })
const handleSubmit = (e) => {
e.preventDefault()
console.log(name, email, message)
emailjs
.sendForm(
'service_8cyr6cf', 'template_0koo5jf', e.target, 'TtcKG0LCV4-mP5FnV'
)
.then(
(result) => {
console.log(result.text)
clearState()
},
(error) => {
console.log(error.text)
}
)
}
emailjs only handles the sending email part. If you want to display something on your UI, you need to create some HTML to display it.
Something like:
export const Contact = (props) => {
const [{ name, email, message }, setState] = useState(initialState)
const [statusMessage, setStatusMessage] = useState("");
const handleChange = (e) => {
const { name, value } = e.target
setState((prevState) => ({ ...prevState, [name]: value }))
}
const clearState = () => setState({ ...initialState })
const handleSubmit = (e) => {
e.preventDefault()
console.log(name, email, message)
emailjs
.sendForm(
'service_8cyr6cf', 'template_0koo5jf', e.target, 'TtcKG0LCV4-mP5FnV'
)
.then(
(result) => {
console.log(result.text, result.status);
clearState();
setStatusMessage("Email sent success");
},
(error) => {
console.log(error.text);
setStatusMessage(`${error.text} happened`);
}
)
}
return
(
<div>
<form></form>
<p>{statusMessage}</p>
</div>
)

React: props has a value at first render afterwards is undefined

export const Modal = (props, { farm, id }) => {
const [currentUser, setCurrentUser] = useState();
console.log("NewId", props.id);
const initialFieldValues = {
title: "",
image: "",
product: "",
content: "",
phone: "",
email: "",
};
const [values, setValues] = useState(initialFieldValues);
function handleChange(e) {
const { name, value } = e.target;
setValues({
...values,
[name]: value,
});
}
const handleFormSubmit = (e) => {
e.preventDefault();
const obj = {
...values,
};
getFirebase()
.database()
.ref(`Users/${props.id}`)
// .ref(`Users/${newId}`)
.push(obj, (err) => {
if (err) console.log(err);
// console.log("ID", newId);
});
};
PARENT COMPONENT
const App = (props) => {
const [currentUser, setCurrentUser] = useState();
const [id, setId] = useState("");
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(async (userAuth) => {
if (userAuth) {
const userRef = await createUserProfileDocument(userAuth);
userRef.on("value", (snapShot) => {
setCurrentUser({ key: snapShot.key, ...snapShot.val() });
});
// }
}
if (setCurrentUser(userAuth)) {
} else if (!userAuth && typeof window !== "undefined") {
return null;
}
const id = userAuth.uid;
setId(id);
});
<>
<Modal id={id} />
</>;
return unsubscribe;
}, []);
When i console.log it here .ref(Users/${props.id}) it's undefined.
This is how my console looks like:
12modal.jsx:12 'NewId' fRHyyzzEotPpIGUkkqJkKQnrTOF2
12modal.jsx:12 'NewId' undefined
it comes one time with the ID and 12 times undifiend.
Any advice would be greatly appreciated.
Firstly you can't change a props values, and if props.id is a state(i.e. const [id, setId] = React.useState(initial value)) then you can change id only by setId which is not received by child, so i think parent might be causing this issue.

remove duplicate user if they has same email

if the user want to add exist email,then it will show a alert that 'user already exist',i have tried various array method like map,filter but i have failed.
const Todo = () => {
const [getName, setName] = useState("");
const [getEmail, setEmail] = useState("");
const [user, setUser] = useState([]);
const nameHandle = (e) => {
setName(e.target.value);
};
const emailHandle = (e) => {
setEmail(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
if (getName !== "" && getEmail !== "") {
const userDetails = {
userId: uuidv4(),
name: getName,
email: getEmail,
};
setUser([...user, userDetails]);
}
};
const deleteUser=(e,userId)=>{
console.log(userId);
e.preventDefault();
setUser(user.filter(value=>value.userId!==userId))
console.log(user);
}
You could use:
if (user.some(value => value.email === getEmail)) {
// email already used!
}

How to get e.target.name in react-datetime picker?

I'm creating a form that can get time value of time picker.
But due to the e is already the Moment, I cant get the input name in handleChange.
Is there a way to get it?
Component:
<DateTimeRangePicker
selected={time}
onChange={handleChange}
type='timepicker'
readOnly={false}
texts={{
name: 'time',
placeholder: 'Enter your time out'
}}
timeFormat='HH:MM:SS'
/>
the texts?.name will be a props and will be inside of innerProps of DatetimepickerProps
CustomForm handleChange
const [values, setValues] = useState(initialState)
const [data, setData] = useState(initialState)
const handleChange = useCallback(
(e: any) => {
let result: any
setValues({ ...values, [e.target.name]: e })
if (e._isValid === true) {
result = {
value: e._d,
status: true
}
} else {
result = {
value: e._d,
status: false
}
}
setData({ ...data, [e.target.name]: result })
},
[data]
)
It has to be e.target.name, since the CustomForm onSubmit will get the other input component throught its e.target.name
For the component DateTimeRangePicker from react-datetime-picker
What you receive from the picker onChange, is not the typical event that you would get from a Jsx element; rather it is the time value of the picker
You can see it in the source code via this link
A solution would be to wrap your handleChange and use a constant to define the name of your property as follow
const TIME_NAME = "time";
const YourComponent = () => {
const [values, setValues] = useState(initialState)
const [data, setData] = useState(initialState)
const handleChange = useCallback(
(e: any) => {
let result: any
setValues({ ...values, [e.target.name]: e.target.value })
if (e._isValid === true) {
result = {
value: e.target.value,
status: true
}
} else {
result = {
value: e.target.value,
status: false
}
}
setData({ ...data, [e.target.name]: result })
},
[data]
);
const handleDateTimeRangePickerChange = (_value) => {
handleChange({target: {name: TIME_NAME, value: _value }});
}
return <DateTimeRangePicker
name={TIME_NAME}
selected={time}
onChange={handleDateTimeRangePickerChange}
type='timepicker'
readOnly={false}
texts={{
name: 'time',
placeholder: 'Enter your time out'
}}
timeFormat='HH:MM:SS'
/>
}

useEffect to manipulate secondary value

Hi im making an interactive price calculator for a sales site that allows the user to click on features that increase a numeric value. I have decided to do the entire thing in useState useEffect before i bring in context to the website.
What you are seeing is the useeffect part i dont want to bring in context yet but im setting up to do that later.
const ToolSelect = () => {
useEffect(() => {
setInitialState(initialState);
}, []);
const [initialState, setInitialState] = useState({
service: "",
services: [],
plan: "",
type: "",
clicked: false,
price: 0
});
const { number, service } = initialState;
useEffect(() => {
if (type === "cash") {
setPrice(number * 1.1);
} else if (type === "accrual") {
setPrice(number * 1.2);
}
});
useEffect(() => {
setClicked(true);
if (plan === "starter") {
setPrice(1000);
} else if (plan === "essential") {
setPrice(2000);
}
});
useEffect(() => {
if (service === "tp") {
services.push(service);
setPrice(number + 800);
} else if (service === "pr") {
services.push(service);
setPrice(number + 1000);
} else if (service === "entity") {
services.push(service);
setPrice(number + 300);
} else if (service === "compliance") {
services.push(service);
setPrice(number + 2000);
}
});
const [price, setPrice] = useState(0);
const [type, setType] = useState("");
const [plan, setPlan] = useState("");
const [services, setServices] = useState([]);
const [clicked, setClicked] = useState(true);
const onChange = e => {
setPrice({ ...price, [e.target.name]: e.target.value });
setType({ ...type, [e.target.name]: e.target.value });
setPlan({ ...plan, [e.target.name]: e.target.value });
setServices({ ...service, [e.target.name]: e.target.value });
};
const onSubmit = e => {
e.preventDefault();
};

Resources