Hello Community, I am new to the Mern-Stack. Currently I am building my dasboard and wants to update an article with image, but I am getting the error:
Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.
And nothing is updated. I would be glad, if someone could help me out.
That is my react:
const MainnewsEdit = () => {
const {mainnews, isLoading, isError, message} = useSelector((state)=>state.mainnews);
// Bringing in the saved data
const savedData = {
img:"",
ressort:"",
theme:"",
title:"",
content:"",
};
const [data, setData] = useState(savedData);
const {img, ressort, theme, title, content} = data;
//logic
const dispatch = useDispatch();
const {id} = useParams();
useEffect(()=>{
if(isError){
window.alert(message);
}
dispatch(getMainNews(id));
return ()=>{
dispatch(reset());
}
},[dispatch, isError, id, message]);
//Bring Data into savedData
useEffect(()=>{
if(mainnews){
setData({...mainnews});
}
return ()=>{
dispatch(reset());
}
},[mainnews, dispatch,]);
console.log(img, ressort, theme, title, content);
const updateData = (name)=> (e)=>{
const value = name === "img" ? e.target.files : e.target.value;
setData({...data, [name]:value})
// setData((prevState)=>({
// ...prevState,
// [e.target.name]:e.target.value,
// }))
}
console.log(data);
const onSubmit = (e)=>{
e.preventDefault();
const mainnewsData = new FormData();
// mainnewsData.append("_id", data.id)
mainnewsData.append("ressort", data.ressort);
mainnewsData.append("theme", data.theme);
mainnewsData.append("title", data.title);
mainnewsData.append("content", data.content);
mainnewsData.append("img", data.img);
for(let value of mainnewsData){
console.log(value);
}
dispatch(updateMainNews(mainnewsData))
}
That is my redux-slice:
export const updateMainNews = createAsyncThunk("mainNews/update", async (id,mainnewsData, thunkAPI)=>{
try{
const token = thunkAPI.getState().auth.user.accessToken;
return await mainnewsService.updateMainNews(id, mainnewsData, token);
} catch(error){
const message = (error.response
&& error.response.data
&& error.response.data.message)
|| error.message
|| error.toString();
return thunkAPI.rejectWithValue(message);
}
})
That is my redux-service:
const updateMainNews = async (mainNewsId, mainnewsData, token)=>{
const config = {
headers:{
'Content-Type':'application/json',
token: `Bearer ${token}`}
}
const response = await axios.put(API_URL + mainNewsId, mainnewsData, config);
return response.data;
}
That is my backend:
router.put("/:id", upload.single("img"), verifyTokenAndAuthorization, async (req,res)=>{
try{
let updatedMainNews = await MainNews.findById(req.params.id);
//destroy
if(req.file){
await cloudinary.uploader.destroy(updatedMainNews.cloudinary_id);
//upload
const updateResult = await cloudinary.uploader.upload(req.file.path, {
upload_preset: "Mern_redux-practice",
resource_type: "auto",
})
}
const updatedData = {
ressort: req.body.ressort || updatedMainNews.ressort,
theme: req.body.theme || updatedMainNews.theme,
title: req.body.title || updatedMainNews.title,
content: req.body.content || updatedMainNews.content,
cloudinary_id: updateResult.cloudinary_id || d.cloudinary_id,
img: updateResult.secure_url || updatedMainNews.secure_url,
}
updatedMainNews = await findByIdAndUpdate(req.params.id, updatedData, {
new:true,
})
res.status(200).json(updatedMainNews);
} catch(error){
res.status(404)
throw new Error("Not found");
}
});
Thanks