onBlur, onChange, onClick on react is triggering twice - reactjs

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

Related

How to upload image in react

I am working on a e-commerce app and there I am using form to add new product in app for that I am taking multiple inputs from user and then I am storing those inputs in my redux store and finally I am displaying newly added product in my app and everything is working perfectly here earlier I was using <input type="url"/> so user can paste an image url so I can display it and it was working perfectly but now I want to allow user so he can upload an Image from his local system instead or url using <input type="file"/> but this isn,t working this is not loading image from local system so is there any way I can upload Image from local system:
Form
import "./ProductForm.css";
import { useReducer } from "react";
import { useDispatch } from "react-redux";
import { addProductHandler } from "../../store/DataStore";
import { useNavigate } from "react-router-dom";
const ProductForm = () => {
const Dispatch = useDispatch();
const navigate = useNavigate();
const initialState = {
product_id: "",
product_name: "",
product_quantity: "",
product_description: "",
product_type: "",
product_valid: "false",
product_price: "",
product_title: "",
product_image: "",
};
const reducer = (state, action) => {
if (action.type === "id") {
return { ...state, product_id: action.value };
} else if (action.type === "name") {
return { ...state, product_name: action.value };
} else if (action.type === "title") {
return { ...state, product_title: action.value };
} else if (action.type === "price") {
return { ...state, product_price: action.value };
} else if (action.type === "image") {
return { ...state, product_image: action.value };
} else if (action.type === "description") {
return { ...state, product_discription: action.value };
} else if (action.type === "type") {
return { ...state, product_type: action.value };
}
};
const [state, dispatch] = useReducer(reducer, initialState);
const submitHandler = (e) => {
e.preventDefault();
const obj = {
product_id: state.product_id,
product_name: state.product_name,
product_price: +state.product_price,
product_title: state.product_title,
product_image: state.product_image,
product_type: state.product_type,
product_description: state.product_discription,
product_quantity: 0,
product_valid: "false",
};
console.log(obj);
// Dispatch(addProductHandler(obj));
// navigate(`/product`, { replace: true });
};
return (
<form onSubmit={submitHandler}>
<legend>
<center>
<h2>
<b>Add Product</b>
</h2>
</center>
</legend>
<div className="form-group">
<label>Product id</label>
<input
type="text"
className="form-control"
value={state.product_id}
onChange={(e) => dispatch({ type: "id", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Name</label>
<input
type="text"
className="form-control"
value={state.product_name}
onChange={(e) => dispatch({ type: "name", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Price</label>
<input
type="text"
className="form-control"
value={state.product_price}
onChange={(e) => dispatch({ type: "price", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Title</label>
<input
type="text"
className="form-control"
value={state.product_title}
onChange={(e) => dispatch({ type: "title", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Type</label>
<select
className="form-control"
value={state.product_type}
onChange={(e) => dispatch({ type: "type", value: e.target.value })}
>
<option value="" selected disabled>
Select one
</option>
<option value="c1">Commodityies</option>
<option value="g1">Gadgets</option>
<option value="w1">Wearings</option>
</select>
</div>
<div className="form-group">
<label>Product Image</label>
<input
type="file"
className="form-control"
value={state.product_image}
onChange={(e) => dispatch({ type: "image", value: e.target.value })}
/>
</div>
<div className="form-group">
<label>Product Description</label>
<textarea
className="form-control"
id=""
rows="7"
value={state.product_discription}
onChange={(e) =>
dispatch({ type: "description", value: e.target.value })
}
></textarea>
</div>
<button type="submit" className="btn btn-primary mt-4">
Submit
</button>
</form>
);
};
export default ProductForm;
you cannot upload file like that you should have to use FormData Class For multipart/form-data
var formData = new FormData();
formData.append('product_id', state.product_id,)
formData.append('product_name', state.product_name,)
formData.append('product_price', +state.product_price,)
formData.append('product_title', state.product_title,)
formData.append('product_image', state.product_image,)
formData.append('product_type', state.product_type,)
formData.append('product_description', state.product_discription,)
formData.append('product_quantity', 0,)
formData.append('product_valid', "false")
formData.append('image', $('input[type=file]')[0].files[0]);
$.ajax({
url: 'Your url here',
data: formData,
type: 'POST',
contentType: false, // NEEDED, DON'T OMIT THIS (requires jQuery 1.6+)
processData: false, // NEEDED, DON'T OMIT THIS
// ... Other options like success and etc
});
After this it will send ajax request like you submit regular form
with enctype="multipart/form-data"

Diffrent Input type using Bootstrap desing in Redux-React functional componnent

Im trying to display my data in diffrent Form inputs, but in some of them, i dont know how to reach my data.
//DashShowDetails.js:
import { useState, useEffect } from 'react';
import { Button, Form } from 'react-bootstrap';
import { Input, Label } from 'reactstrap';
function DashShowDetails(props) {
const { data } = props;
const [edit, setEdit] = useState(false);
const [formData, setFormData] = useState({
id: data._id,
showId: data.showId,
showName: data.name,
showGenres: data.genres,
showStatus: data.status,
showPremiered: data.premiered,
showEnded: data.ended,
showRating: data.rating,
showSummery: data.summary,
showImage: data.image,
});
const onClick = () => {
setEdit(current => !current)
}
const onChange = (e) => {
setFormData((prevState) => ({
...prevState,
[e.target.name]: e.target.value
}))
}
const onSubmit = async (e) => {
e.preventDefault()
let show = formData;
dispatch(updateDashShow(show));
setEdit(current => !current);
setFormData((prevState) => ({
...prevState,
}))
}
useEffect(() => {
}, [edit]);
return (
<div>
<div>
<h5>{data.name}</h5>
<Button onClick={onClick}>Edit Show</Button>
</div>
<div>
{edit === true && (
<div>
<h3>Edit {data.name}</h3>
<Form onSubmit={onSubmit} >
<div>
<Label>Show ID:</Label>
<Input type="text" name="showId" value={data.showId} onChange={onChange} />
</div>
<div>
<Label>Show Name:</Label>
<Input type="text" name="showName" defaultValue={data.name} onChange={onChange} />
</div>
<div>
<Label>Show Genres:</Label>
<Input type="text" name="showGenres" defaultValue={data.genres} onChange={onChange} />
</div>
<div>
<Label>Show Status:</Label>
<Input type="select" name="showStatus" select={data.status} onChange={onChange}>
<option value="running">Running</option>
<option value="ended">Ended</option>
</Input>
</div>
<div>
<Label>Premiered Date:</Label>
<Input type="date" name="showPremiered" value={data.premiered} onChange={onChange} />
</div>
<div>
<Label>Ended Date:</Label>
<Input type="date" name="showEnded" value={data.ended} onChange={onChange} />
</div>
<div>
<Label>Show Rating:</Label>
<Input type="array" name="showRating" value={data.rating} onChange={onChange} />
</div>
<div>
<Label>Show Summery:</Label>
<Input type="textarea" name="showSummery" value={data.summery} onChange={onChange} />
</div>
<div>
<Label>Image:</Label>
</div>
<Button type="submit">Update Show</Button>
<Button>Delete Show</Button>
</Form>
</div>
)}
</div>
</div>
);
}
export default DashShowDetails;
My output when i click 'Edit Show' is:
How can i display my Data in inputs: Premiered Date, Show Rating, Show Summery & Image?
My Schema file in Node.js: (sending new data to MoongoDB)
const showSchema = new mongoose.Schema({
showId: {type: Number},
name: {type: String},
genres: {type: Array},
status: {type: String},//Boolean
premiered: {type: Date},
ended: {type: Date},
rating: {type: Array},
summary: {type: String},
image: {type: Array},//Link?File?
})
module.exports = mongoose.model('shows', showSchema);

How can I get radio button value in React?

I have three radio buttons and I need to put the value of the selected one in inputs.reply, just like I did with inputs.name, inputs.email, inputs.phone and inputs.message. How can I do this? I know it's probably a very easy thing to do, but I've been trying for hours and it doesn't work.
import Head from 'next/head'
import React, { useState } from 'react'
export default () => {
const [status, setStatus] = useState({
submitted: false,
submitting: false,
info: { error: false, msg: null }
})
const [inputs, setInputs] = useState({
reply: '',
name: '',
phone: '',
email: '',
message: ''
})
function SubmitButton(){
if (inputs.name && inputs.email && inputs.message) {
return <button type="submit" className="btn-submit" disabled={status.submitting}> {!status.submitting ? !status.submitted ? 'Submit' : 'Submitted' : 'Submitting...'} </button>
} else {
return <button type="submit" className="btn-submit" disabled>Submit</button>
};
};
const handleResponse = (status, msg) => {
if (status === 200) {
setStatus({
submitted: true,
submitting: false,
info: { error: false, msg: msg }
})
setInputs({
reply: '',
name: '',
phone: '',
email: '',
message: ''
})
} else {
setStatus({
info: { error: true, msg: msg }
})
}
}
const handleOnChange = e => {
e.persist()
setInputs(prev => ({
...prev,
[e.target.id]: e.target.value
}))
setStatus({
submitted: false,
submitting: false,
info: { error: false, msg: null }
})
}
const handleOnSubmit = async e => {
e.preventDefault()
setStatus(prevStatus => ({ ...prevStatus, submitting: true }))
const res = await fetch('/api/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(inputs)
})
const text = await res.text()
handleResponse(res.status, text)
}
return (
<div className="contact">
<main>
<div className="content">
<div>
<h2>Get in touch!</h2>
<h3>How can we help you?</h3>
</div>
<form onSubmit={handleOnSubmit}>
<h4>How would you like us to get back to you?</h4>
<div className="form-group form-group-radio">
<div>
<input type="radio" onChange={handleOnChange} value="Phone" name="email-reply" id="reply-phone" />
<label className="radio-label" htmlFor="reply-phone">Phone</label>
</div>
<div>
<input type="radio" onChange={handleOnChange} value="E-mail" name="email-reply" id="reply-email" />
<label className="radio-label" htmlFor="reply-email">E-mail</label>
</div>
<div>
<input type="radio" onChange={handleOnChange} value="No reply needed" name="email-reply" id="no-reply" />
<label className="radio-label" htmlFor="no-reply">No reply needed</label>
</div>
</div>
<div className="form-group">
<input
id="name"
type="text"
name="name"
onChange={handleOnChange}
required
value={inputs.name}
className={inputs.name ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="name">Name</label>
</div>
<div className="form-group">
<input
id="email"
type="text"
name="email"
onChange={handleOnChange}
required
value={inputs.email}
className={inputs.email ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="email">Email</label>
</div>
<div className="form-group">
<input
id="phone"
type="tel"
name="phone"
onChange={handleOnChange}
required
value={inputs.phone}
className={inputs.phone ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="phone">Phone</label>
</div>
<div className="form-group">
<textarea
id="message"
onChange={handleOnChange}
required
value={inputs.message}
className={inputs.message ? "form-control active" : "form-control"}
/>
<label className="form-label" htmlFor="message">Message</label>
</div>
<SubmitButton />
{status.info.error && (
<div className="message-feedback error">
<p>Error: {status.info.msg}</p>
</div>
)}
{!status.info.error && status.info.msg && (
<div className="message-feedback success">
<p>Thanks for messaging us!</p>
<p>We'll get back to you soon.</p>
</div>
)}
</form>
</div>
</main>
</div>
)
}
Thank you.
Remove the id attribute from all of the <input type="radio" /> and instead add a name="reply" to all of them.
Now update handleOnChange, specifically this part
setInputs(prev => ({
...prev,
[e.target.id || e.target.name]: e.target.value
}))
You can update the handleOnChange method to check for the type of the target event and if its a radio button, you can update the radio state, otherwise use the dynamic key to update the state.
const handleOnChange = (e) => {
e.persist();
const key = e.target.type === "radio" ? "reply" : e.target.id;
setInputs((prev) => ({
...prev,
[key]: e.target.value
}));
setStatus({
submitted: false,
submitting: false,
info: { error: false, msg: null }
});
};

value of the option selected not passing in react

Trying to get a response when clicking and store the selected option from the selected value genre, not sure how to add a select new state variable or a post method. When the option is clicked the click handler is not called with the selected options so that we can add it to the state. My genre is also seen as undefined when I don't click on the the text type.
Feedback.js
import React, { useState } from "react";
import axios from "axios";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.min.css";
import Layout from "./Layout";
const Feedback = () => {
const [values, setValues] = useState({
name: "",
artist: "",
songTitle: "",
email: "",
message: "",
phone: "",
genre: "",
uploadedFiles: [],
buttonText: "Submit",
uploadPhotosButtonText: "Upload files",
});
// destructure state variables
const {
name,
artist,
songTitle,
label,
email,
message,
phone,
genre,
uploadedFiles,
buttonText,
uploadPhotosButtonText,
} = values;
// destructure env variables
const {
REACT_APP_API,
REACT_APP_CLOUDINARY_CLOUD_NAME,
REACT_APP_CLOUDINARY_UPLOAD_SECRET,
} = process.env;
// event handler
const handleChange = (name) => (event) => {
setValues({ ...values, [name]: event.target.value });
};
const handleSubmit = (event) => {
event.preventDefault();
setValues({ ...values, buttonText: "...sending" });
// send to backend for email
console.table({ name, email, phone, message, uploadedFiles, genre });
axios({
method: "POST",
url: `${REACT_APP_API}/feedback`,
data: {
name,
artist,
songTitle,
label,
email,
genre,
phone,
message,
uploadedFiles,
},
})
.then((response) => {
// console.log('feedback submit response', response);
if (response.data.success) toast.success("Thanks for your feedback");
setValues({
...values,
name: "",
artist: "",
songTitle: "",
label: "",
phone: "",
email: "",
genre: "",
message: "",
uploadedFiles: [],
buttonText: "Submitted",
uploadPhotosButtonText: "Uploaded",
});
})
.catch((error) => {
// console.log('feedback submit error', error.response);
if (error.response.data.error) toast.error("Failed! Try again!");
});
};
function onChangeInput(value) {
console.log(value);
}
const uploadWidget = () => {
window.cloudinary.openUploadWidget(
{
cloud_name: REACT_APP_CLOUDINARY_CLOUD_NAME,
upload_preset: REACT_APP_CLOUDINARY_UPLOAD_SECRET,
tags: ["ebooks"],
},
function (error, result) {
// console.log(result);
setValues({
...values,
uploadedFiles: result,
uploadPhotosButtonText: `${
result ? result.length : 0
} Photos uploaded`,
});
}
);
};
const feedbackForm = () => (
<React.Fragment>
<div className="form-group">
<button
onClick={() => uploadWidget()}
className="btn btn-outline-secondary btn-block p-5"
>
{uploadPhotosButtonText}
</button>
</div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label className="text-muted">Description</label>
<textarea
onChange={handleChange("message")}
type="text"
className="form-control"
value={message}
required
></textarea>
</div>
<div className="form-group">
<label className="text-muted">Your Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("name")}
value={name}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Your Email</label>
<input
className="form-control"
type="email"
onChange={handleChange("email")}
value={email}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Your Phone</label>
<input
className="form-control"
type="number"
onChange={handleChange("phone")}
value={phone}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Artist Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("artist")}
value={artist}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Song Title</label>
<input
className="form-control"
type="text"
onChange={handleChange("songTitle")}
value={songTitle}
required
/>
</div>
<div className="form-group">
<label className="text-muted">Record Label Name</label>
<input
className="form-control"
type="text"
onChange={handleChange("label")}
value={label}
/>
</div>
<div className="form-group">
<label className="text-muted">Music Genre:</label>
<select
className="form-control"
value={genre}
type="select"
onChange={handleChange("genre")}
>
<option value="steak">Steak</option>
<option value="sandwich">Sandwich</option>
<option value="dumpling">Dumpling</option>
</select>
</div>
<button className="btn btn-outline-primary btn-block">
{buttonText}
</button>
</form>
</React.Fragment>
);
return (
<Layout>
<ToastContainer />
<div className="container text-center">
<h1 className="p-5">Feedback Online</h1>
</div>
<div className="container col-md-8 offset-md-2">{feedbackForm()}</div>
<br />
<br />
<br />
</Layout>
);
};
export default Feedback;

why am i getting undefined for match object in react.js

The below code is to update a product in admin panel. I have manage to do everything except that on a button pressed for update i want to fetch the url from the above address bar. I thought of using match.params.productId. Here produtId is what i wanted ti get. But i dont know why the match object returns undefined..PLease help me to get rid of this.
import React, { useState, useEffect } from "react";
import Base from "../core/Base";
import { Link } from "react-router-dom";
import {
getAllCategories,
getProduct,
updateProduct
} from "./helper/adminapicall";
import { isAuthenticated } from "../auth/helper/index";
const UpdateProduct = ({ match }) => {
const { user, token } = isAuthenticated();
const [values, setValues] = useState({
name: "",
description: "",
price: "",
stock: "",
photo: "",
categories: [],
category: "",
loading: false,
error: "",
createdProduct: "",
getaRedirect: false,
formData: ""
});
const {
name,
description,
price,
stock,
categories,
category,
loading,
error,
createdProduct,
getaRedirect,
formData
} = values;
const preload = (productId) => {
getProduct(productId).then((data) => {
console.log(data);
if (data.error) {
setValues({ ...values, error: data.error });
} else {
preloadCategories();
setValues({
...values,
name: data.name,
description: data.description,
price: data.price,
category: data.category._id,
stock: data.stock,
formData: new FormData()
});
}
});
};
const preloadCategories = () => {
getAllCategories().then((data) => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
categories: data,
formData: new FormData()
});
}
});
};
useEffect(() => {
//console.log(match);
preload(match.params.productId);
}, []);
//TODO: work on it
const onSubmit = (event) => {
event.preventDefault();
setValues({ ...values, error: "", loading: true });
updateProduct(match.params.productId, user._id, token, formData).then(
(data) => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
name: "",
description: "",
price: "",
photo: "",
stock: "",
loading: false,
createdProduct: data.name
});
}
}
);
};
const handleChange = (name) => (event) => {
const value = name === "photo" ? event.target.files[0] : event.target.value;
formData.set(name, value);
setValues({ ...values, [name]: value });
};
const successMessage = () => (
<div
className="alert alert-success mt-3"
style={{ display: createdProduct ? "" : "none" }}
>
<h4>{createdProduct} updated successfully</h4>
</div>
);
const createProductForm = () => (
<form>
<span>Post photo</span>
<div className="form-group">
<label className="btn btn-block btn-success">
<input
onChange={handleChange("photo")}
type="file"
name="photo"
accept="image"
placeholder="choose a file"
/>
</label>
</div>
<div className="form-group">
<input
onChange={handleChange("name")}
name="photo"
className="form-control"
placeholder="Name"
value={name}
/>
</div>
<div className="form-group">
<textarea
onChange={handleChange("description")}
name="photo"
className="form-control"
placeholder="Description"
value={description}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("price")}
type="number"
className="form-control"
placeholder="Price"
value={price}
/>
</div>
<div className="form-group">
<select
onChange={handleChange("category")}
className="form-control"
placeholder="Category"
>
<option>Select</option>
{categories &&
categories.map((cate, index) => (
<option key={index} value={cate._id}>
{cate.name}
</option>
))}
</select>
</div>
<div className="form-group">
<input
onChange={handleChange("stock")}
type="number"
className="form-control"
placeholder="Stock"
value={stock}
/>
</div>
<button
type="submit"
onClick={onSubmit}
className="btn btn-outline-success mb-3"
>
Update Product
</button>
</form>
);
return (
<Base
title="Add a product here!"
description="Welcome to product creation section"
className="container bg-info p-4"
>
<Link to="/admin/dashboard" className="btn btn-md btn-dark mb-3">
Admin Home
</Link>
<div className="row bg-dark text-white rounded">
<div className="col-md-8 offset-md-2">
{successMessage()}
{createProductForm()}
</div>
</div>
</Base>
);
};
export default UpdateProduct;

Resources