I am trying to build a form with react. But every onBlur, onChange, and onClick is triggering twice. It happens if i try to console log inside the reducer
function. The JSX is -
import React, { useReducer } from "react";
const LongForm = () => {
const initialState = {
firstName: "",
lastName: "",
email: "",
gender: "",
education: "",
quantity: 0,
feedback: "",
term: false,
};
const reducer = (state, action) => {
switch (action.type) {
case "INPUT": {
return {
...state,
[action.payload.name]: action.payload.value,
};
}
case "TOGGLE": {
return {
...state,
term: !state.term,
};
}
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, initialState);
const submit = (event) => {
event.preventDefault();
};
return (
<div>
<form
onSubmit={submit}
>
<div>
<label htmlFor="firstName">
First Name
</label>
<input
type="text"
name="firstName"
id="firstName"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
</div>
<div>
<label htmlFor="lastName">
Last Name
</label>
<input
type="text"
name="lastName"
id="lastName"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
</div>
<div>
<label htmlFor="email">
Email
</label>
<input
type="email"
name="email"
id="email"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
</div>
<div>
<h1>Gender</h1>
<div>
<div>
<input
type="radio"
id="male"
name="gender"
value="male"
// prints twice
onClick={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
<label htmlFor="male">
Male
</label>
</div>
<div>
<input
type="radio"
id="female"
name="gender"
value="female"
// prints twice
onClick={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
<label htmlFor="female">
Female
</label>
</div>
<div>
<input
type="radio"
id="other"
name="gender"
value="other"
// prints twice
onClick={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
/>
<label htmlFor="other">
Other
</label>
</div>
</div>
</div>
<div>
<label htmlFor="education">
Education
</label>
<select
name="education"
id="education"
// prints twice
onChange={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
>
<option value="SSC">SSC</option>
<option value="HSC">HSC</option>
<option value="underGrad">Under Graduate</option>
<option value="graduate">Graduate</option>
</select>
</div>
<div>
<label>Number of PCs</label>
<div>
<button>
-
</button>
<div>
<span>0</span>
</div>
<button>
+
</button>
</div>
</div>
<div>
<label htmlFor="feedback">
Feedback
</label>
<textarea
name="feedback"
id="feedback"
cols="30"
rows="4"
// prints twice
onBlur={(e) => {
dispatch({
type: "INPUT",
payload: {
name: e.target.name,
value: e.target.value,
},
});
}}
></textarea>
</div>
<div>
<div>
<input
type="checkbox"
name="term"
id="terms"
// prints twice
onClick={() => dispatch({ type: "TOGGLE" })}
/>
<label htmlFor="terms">I agree to terms and conditions</label>
</div>
<button
type="submit"
>
Submit
</button>
</div>
</form>
</div>
);
};
export default LongForm;
I have looked into other problems But I am failing to understand why is it happening to my code. How can I solve this?
try to define these handlers as local functions inside your component. and check if your app wrapped with React.StrictMode