I use Next.js and I'm just trying to add data to the server normally using the fetch
method and thunk, but I get this error:
Error: Function components cannot have string refs. We recommend using useRef() instead.
addBookForm.jsx:
import React, {useRef} from 'react'
import { useDispatch } from 'react-redux'
import { insertBook } from '@/app/redux/Features/bookSlice'
function addBooksForm() {
// ref
const title = useRef(null);
const img = useRef(null);
const descripition = useRef(null);
const bookLinke = useRef(null);
const dispatch = useDispatch();
const handelSubmit = (e) => {
e.preventDefault();
const data = {
name: title.current.value,
photo: img.current.value,
des: descripition.current.value,
link: bookLinke.current.value
};
dispatch(insertBook(data));
title.current.value = null;
img.current.value = null;
descripition.current.value = null;
bookLinke.current.value = null;
}
return (
<div className="w-full px-4 bg-white ">
<div className="max-w-[700px] mx-auto">
<div className="w-full shadow-xl flex flex-col p-4 my-8 rounded-lg ">
<h2 className="text-2xl font-bold text-center py-4">Insert Book</h2>
<form onSubmit={handelSubmit}>
<div className="mb-6">
<label className="block mb-2 text-l font-medium text-gray-900">
Title
</label>
<input
type="text"
className="block w-full p-4 mb-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md "
ref={name}
required
></input>
<label className="block mb-2 text-l font-medium text-gray-900">
Linke of image
</label>
<input
type="text"
className="block w-full p-4 mb-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md "
ref={img}
required
></input>
<label className="block mb-2 text-sm font-medium text-gray-900 ">
Description
</label>
<textarea
id="message"
rows={4}
className="block p-2.5 w-full text-sm mb-4 text-gray-900 bg-gray-50 rounded-lg border border-gray-300"
ref={descripition}
required
></textarea>
<label className="block mb-2 text-l font-medium text-gray-900">
Linke of book
</label>
<input
type="text"
className="block w-full p-4 mb-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md "
ref={bookLinke}
required
></input>
<button
type="submit"
className="text-white bg-[#BDA175] hover:bg-black disabled:bg-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2"
>
Submit
</button>
</div>
</form>
</div>
</div>
</div>
)
}
export default addBooksForm
bookSlice:
"use client";
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
export const insertBook = createAsyncThunk(
"book/insertBook",
async (bookData, thunkAPI) => {
const { rejectWithValue } = thunkAPI;
try {
const res = await fetch("http://localhost:3005/books", {
method: "POST",
body: JSON.stringify(bookData),
headers: {
"Content-type": "application/json; charset=UTF-8",
},
});
const data = await res.json();
return data;
} catch (error) {
return rejectWithValue(error.message);
}
}
);
const bookSlice = createSlice({
name: "book",
initialState: { books: [], isLoading: false, error: null },
reducers: {},
extraReducers: (builder) => {
// INSERT BOOK
builder.addCase(insertBook.pending, (state, action) => {
state.isLoading = true;
state.error = null;
}),
builder.addCase(insertBook.fulfilled, (state, action) => {
state.isLoading = false;
state.books.push(action.payload);
}),
builder.addCase(insertBook.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload;
});
},
});
export default bookSlice.reducer;
How can I fix that error?
I suspect the issue is the
ref={name}
of the title input, there is no definedname
variable though, so I'd expect to see a different error. You likely meant to useref={title}
.That said, the implementation is a bit of an anti-pattern. It is generally preferable to use fully controlled inputs using React state and
onChange
handlers on the inputs, or to use uncontrolled inputs and gather the form field values from theform
element'sonSubmit
event object.Examples
Controlled inputs
Uncontrolled inputs: