I have this Body Component set:
import 'bootstrap/dist/css/bootstrap.css';
import {Container} from "react-bootstrap";
import Navigation from './Navigation'
import axios from 'axios'
import {useState,useEffect} from "react";
function Body() {
const [searchItems, setSearchItems] = useState([{}])
useEffect(() => {
console.log(searchItems)
}, [])
return (
<Container>
<Navigation setSearchItems={setSearchItems}/>
</Container>
);
}
export default Body;
And here is my Navigation Component with an Inputfield as anther component named SearchInput. As you can see I pass the setSearchItems from the start to each child, because I want to use the searchItems-Array to display some data later:
import Navbar from 'react-bootstrap/Navbar';
import Form from 'react-bootstrap/Form';
import {InputGroup} from "react-bootstrap";
import axios from 'axios';
import {useState, useEffect} from "react";
const api_key = process.env.API_KEY;
const SearchInput = (setSearchItems) => {
async function changeHandler(e, setSearchItems) {
if (e.target.value.length > 2) {
const url = 'https://api.thedogapi.com/v1/breeds/search?q=' e.target.value
const config = {
method: 'GET',
mode: 'cors',
headers: {
'x-api-key': api_key
}
}
const data = await axios.get(url, config)
setSearchItems(data['data'])
}
}
return (
<InputGroup style={{
marginLeft: '50px',
marginRight: '50px',
paddingTop: '10px',
paddingBottom: '10px',
width: '50%'
}}>
<Form.Control
placeholder="Enter Dogs Breed"
aria-label="Breed"
onChange={(e) => changeHandler(e, setSearchItems)}
/>
</InputGroup>
)
}
const Navigation = (setSearchInput) => {
return (
<Navbar fixed="top" bg='light'>
<SearchInput setSearchInput={setSearchInput}/>
</Navbar>
)
}
export default Navigation;
everytime I try to call setSearchItems, I get Uncaught (in promise) TypeError: setSearchItems is not a function
I also tried this version of changeHandler before:
async function changeHandler(e) {
if (e.target.value.length > 2) {
const url = 'https://api.thedogapi.com/v1/breeds/search?q=' e.target.value
const config = {
method: 'GET',
mode: 'cors',
headers: {
'x-api-key': api_key
}
}
await axios.get(url, config)
.then((response) => setSearchItems([response.data]))
}
}
but it's an error al the time
CodePudding user response:
Try destructuing it in parameters of component like this: const Component =({setSearchItems}) => {}. It could work because the object that is given to component is actually params that holds all arguments
CodePudding user response:
You could use the concept of prop drilling in React by passing the props from parent to child component and getting values from child components. In your case, Body
is the body component so you can basically drill
the states through components.
So, your Body
component looks like this
import "bootstrap/dist/css/bootstrap.css";
import { Container } from "react-bootstrap";
import Navigation from "./navigation";
import { useState } from "react";
function Body() {
const [searchItems, setSearchItems] = useState([]);
const [searchInput, setSearchInput] = useState("");
return (
<Container>
<Navigation
setSearchItems={setSearchItems}
setSearchInput={setSearchInput}
/>
<ul>
{searchItems.map((item, index) => (
<li key={index}>{item.name}</li>
))}
</ul>
</Container>
);
}
export default Body;
and the Navigation
component is
import Navbar from "react-bootstrap/Navbar";
import SearchInput from "./search";
const Navigation = ({ setSearchItems, setSearchInput }) => {
return (
<Navbar fixed="top" bg="light">
<SearchInput
setSearchInput={setSearchInput}
setSearchItems={setSearchItems}
/>
</Navbar>
);
};
export default Navigation;
and finally Search
component is getting the setSearchItems
as prop and adding the array to it.
import axios from "axios";
import { InputGroup } from "react-bootstrap";
import Form from "react-bootstrap/Form";
const api_key = process.env.API_KEY;
const SearchInput = ({ setSearchItems }) => {
async function changeHandler(e) {
if (e.target.value.length > 2) {
const url =
"https://api.thedogapi.com/v1/breeds/search?q=" e.target.value;
const config = {
method: "GET",
mode: "cors",
headers: {
"x-api-key": api_key
}
};
const data = await axios.get(url, config);
console.log(data);
setSearchItems(data["data"]);
}
}
return (
<InputGroup
style={{
marginLeft: "50px",
marginRight: "50px",
paddingTop: "10px",
paddingBottom: "10px",
width: "50%"
}}
>
<Form.Control
placeholder="Enter Dogs Breed"
aria-label="Breed"
onChange={(e) => changeHandler(e)}
/>
</InputGroup>
);
};
export default SearchInput;
I have added the working demo version here.