I am trying to pass a function from a parent to child component to have the child change the parents state. Basically I have a search bar that needs to change what is displayed on the main page.
When I check the type of the function in the parent it shows up as a function but when I send and check it in the child its type is undefined. I get an error that its not a function whenever I try to call it in the child component
import LineChart from "./charts/LineChart";
import React, { Component } from 'react';
import Player from "../Components/Player";
import SearchBar from '../Components/SearchBar';
class Future extends Component {
state = {
players: [],
data: [],
playerID : ""
};
async componentDidMount() {
if (Player.playerID == "") {
const response = await fetch('http://localhost:8080/random');
const body = await response.json();
this.setState({ players: body });
console.log(body[0].player_id);
this.setState({ playerID: body[0].player_id })
this.setData(body[0].player_id)
} else {
this.displayPlayer(Player.playerID)
this.setData(Player.playerID)
}
}
async displayPlayer(playerID) {
if (playerID != "") {
const response = await fetch('http://localhost:8080/get_player/' playerID);
const body = await response.json();
this.setState({ players: body });
}
}
onSearchChange = (value) => {
this.setState({ playerID: value });
}
async setData(id) {
const response = await fetch('http://localhost:8080/goal_prediction/' id);
const body = await response.json();
this.setState({ data: body });
console.log(body);
}
render() {
this.displayPlayer(Player.playerID)
const { players, data, id } = this.state;
return (
<div>
<SearchBar placeholder={"Search"} stateChange={this.onSearchChange} />
{players.map(player =>
<div key={player.id}>
{player.name}'s goals
</div>
)}
<LineChart />
Goals predicted for next season: {data.predicted_goals }
</div>
);
}
}
export default Future;
import './SearchBar.css';
import React, { useState } from 'react';
import CloseIcon from '@mui/icons-material/Close';
import SearchIcon from '@mui/icons-material/Search';
import Player from '../Components/Player';
import Future from '../pages/FutureStats';
function SearchBar({ placeholder }, { stateChange }) {
const [filteredData, setFilteredData] = useState([]);
const [wordEntered, setWordEntered] = useState("");
const handleFilter = async (event) => {
const searchWord = event.target.value // Access the value inside input
setWordEntered(searchWord);
const url = 'http://localhost:8080/search_player/' searchWord;
const response = await fetch(url);
const body = await response.json();
if (searchWord === "") {
setFilteredData([])
} else {
setFilteredData(body);
}
}
const clearInput = () => {
setFilteredData([]);
setWordEntered("");
}
const selectInput = value => () => {
console.log(Player.playerID)
Player.playerID
setFilteredData([]);
setWordEntered("");
console.log(typeof(stateChange))
stateChange(value);
}
return (
<div className='search'>
<div className='searchInputs'>
<input type={"text"} value={wordEntered} placeholder={placeholder} onChange={handleFilter} />
<div className='searchIcon'>
{filteredData.length === 0 ? <SearchIcon/> : <CloseIcon id="clearButton" onClick={clearInput} />}
</div>
</div>
{filteredData.length !== 0 && (
<div className='dataResult'>
{filteredData.slice(0, 15).map((value) => {
return (
// Stay on one page.
<a className="dataItem" target="_blank" rel="noopener noreferrer" onClick={selectInput(value.player_id)}>
<p key={value.id}>{value.name}</p>
</a>
);
})}
</div>
)}
</div>
);
}
export default SearchBar;
CodePudding user response:
stateChange
is part of your props and needs to be the first argument in your SearchBar
function:
function SearchBar({ placeholder, stateChange }) {
...