I call the function 'booksRefresh()' from the parent in the child component, but I get the error:
TypeError: booksRefresh is not a function
I don't know why, because 'booksRefresh' is a function. Can someone help me explain why this error occurs?
Here is my code:
import React, {useState} from "react";
import {Redirect} from "react-router";
import {addBook} from "../api/api";
import {Button} from "react-bootstrap";
const AddBookForm = (booksRefresh) => {
const [title, setTitle] = useState();
const [description, setDescription] = useState();
const [submitted, setSubmitted] = useState(false);
const postRequestHandler = () => {
addBook(title, description);
booksRefresh();
}
...
return (
...
<Button type="submit" onClick={postRequestHandler} variant="outline-success">Add</Button>
</div>
)
Parent:
function App({history}) {
...
const [changeInBooks, setChangeInBooks] = useState(0)
const booksRefresh = () => {
let incrementChangeInBook = changeInBooks + 1;
setChangeInBooks(incrementChangeInBook)
}
return (
<div className="App">
<header className="App-header">
...
<Button variant="outline-success" onClick={() => history.push("/new-book")}>
{ADD_BOOK}</Button>
...
</header>
<Switch>
...
<Route path="/new-book" exact render={() =>
<AddBookForm
booksRefresh={booksRefresh}/>
}/>
...
</Switch>
</div>
);
}
export default withRouter(App);
I call the function 'booksRefresh()' from the parent in the child component, but I get the error:
TypeError: booksRefresh is not a function
I don't know why, because 'booksRefresh' is a function. Can someone help me explain why this error occurs?
Here is my code:
import React, {useState} from "react";
import {Redirect} from "react-router";
import {addBook} from "../api/api";
import {Button} from "react-bootstrap";
const AddBookForm = (booksRefresh) => {
const [title, setTitle] = useState();
const [description, setDescription] = useState();
const [submitted, setSubmitted] = useState(false);
const postRequestHandler = () => {
addBook(title, description);
booksRefresh();
}
...
return (
...
<Button type="submit" onClick={postRequestHandler} variant="outline-success">Add</Button>
</div>
)
Parent:
function App({history}) {
...
const [changeInBooks, setChangeInBooks] = useState(0)
const booksRefresh = () => {
let incrementChangeInBook = changeInBooks + 1;
setChangeInBooks(incrementChangeInBook)
}
return (
<div className="App">
<header className="App-header">
...
<Button variant="outline-success" onClick={() => history.push("/new-book")}>
{ADD_BOOK}</Button>
...
</header>
<Switch>
...
<Route path="/new-book" exact render={() =>
<AddBookForm
booksRefresh={booksRefresh}/>
}/>
...
</Switch>
</div>
);
}
export default withRouter(App);
Share
Improve this question
asked Jan 9, 2020 at 12:17
werwer
2011 gold badge4 silver badges12 bronze badges
2
|
4 Answers
Reset to default 17The argument a React function component receives is its props, which is an object with named properties for each of the properties. So your AddBookForm
's parameter shouldn't be booksRefresh
, but (by convention) props
, and then you use it via props.booksRefresh()
:
const AddBookForm = (props) => {
// −−−−−−−−−−−−−−−−−−^^^^^
const [title, setTitle] = useState();
const [description, setDescription] = useState();
const [submitted, setSubmitted] = useState(false);
const postRequestHandler = () => {
addBook(title, description);
props.booksRefresh();
// −−−−−^^^^^^
}
// ...
Or if it's the only prop, you can use destructuring as adiga shows:
const AddBookForm = ({booksRefresh}) => {
const AddBookForm = ({booksRefresh}) => {
const [title, setTitle] = useState();
const [description, setDescription] = useState();
const [submitted, setSubmitted] = useState(false);
const postRequestHandler = () => {
addBook(title, description);
booksRefresh();
}
try this i hope it works
because of props.booksRefresh is a function
The props parameter is an object with a property called booksRefresh
inside it.
Use destructuring to get the property
const AddBookForm = ({ booksRefresh }) => {
}
You are already doing it to get history
in the App
component
Because first argument of functional component is props
function Component(props) {
}
You have to retrieve prop by name
function Component(props) {
const prop = props.propName
}
Or using destructuring
function Component({propName) {
}
const AddBookForm = ({ booksRefresh })
you have to spread the props. – Thirueswaran Rajagopalan Commented Jan 9, 2020 at 12:20