I have a simple site which loads property-related data from a Danish national data provider, SDFI.
I am having issues passing down the right values from a mother component to a sub component.
My code looks like this:
My main component:
Search.js:
import { Container } from "react-bootstrap";
import { useState } from "react";
import { AsyncTypeahead } from "react-bootstrap-typeahead";
import ResultsDisplay from './ResultsDisplay';
const SEARCH_URI = "https://api.dataforsyningen.dk/autocomplete";
const AsyncSearch = () => {
const [isLoading, setIsLoading] = useState(false);
const [options, setOptions] = useState([]);
const [found, setFound] = useState(false);
const [hest, setHest] = useState([])
const [grund, setGrund] = useState(0)
const handleSearch = async (query) => {
setIsLoading(true);
const response = await fetch(`${SEARCH_URI}?q=${query}&type=adresse`);
const addresses = await response.json();
setOptions(addresses);
console.log(addresses);
setIsLoading(false);
};
const handleChange = async (selected) => {
if (selected === undefined || selected.length == 0 )
return;
const s = selected[0]
const aga = s.data.adgangsadresseid;
// console.log(`1. id = ${s.data.id}`)
// console.log(`2. id = ${s.data.adgangsadresseid}`)
// console.log(`id is ${selected[0].data.adgangsadresseid}`);
let res;
if (s.data.adgangsadresseid === undefined)
{
res = await fetch(`/bolig/${selected[0].data.id}`);
} else {
res = await fetch(`/bolig/${selected[0].data.adgangsadresseid}`);
}
let searchResults = await res.json();
setHest(searchResults);
console.log(hest);
setFound(true);
// Fetch boliggrundareal
const jordstykkeId = searchResults[0].jordstykke;
const matRes = await fetch(`/grundareal/${jordstykkeId}`);
const grund = await matRes.json();
setGrund(grund.grundareal);
}
// Bypass client- side filtering by returning `true`. Results are already
// filtered by the search endpoint, so no to do>it again.
const filterBy = () => true;
return (
<>
<AsyncTypeahead
filterBy={filterBy}
id="async-load"
isLoading={isLoading}
labelKey="forslagstekst"
onChange={handleChange}
minLength={3}
onSearch={handleSearch}
options={options}
placeholder="Indtast adresse"
renderMenuItemChildren={(opt) => (
<>
<span>{opt.tekst}</span>
</>
)}
/>
{hest.length > 0 &&
<ResultsDisplay
grund={grund}
hest={hest}
/>
}
</>
);
}
export default AsyncSearch;
Child component (ResultsDisplay.js)
import { useState } from "react"
import { Container } from 'react-bootstrap';
const ResultsDisplay = (hest, grund) => {
console.log(`grund = ${grund}`)
return(
<>
<Container>
<h2>Grund</h2>
<p>{grund.grundareal}</p>
</Container>
{hest.hest.map((h, i) => {
return (
<Container>
<h2>Bygning</h2>
// ------ <snip> -----
</Container>);
})}
</>
);
}
export default ResultsDisplay;
In the above example, the value of "grund" is never passed correctly from AsyncSearch to ResultsDisplay. If I debug the value of grund.grundareal inside AsyncSearch the value is correct (i.e. it’s an object with the property grundareal = some integer). However, after passing "grund" to ResultsDisplay, it shows up simply as an empty object.
What am I doing wrong? Could this be related to how the "grund" object is passed over to ResultsDisplay?
2
Answers
There might be an issue that you are not getting the values right as expected.
You should try the following
({hest, grund})
instead of(hest, grund)
As you are already DE-structuring the parameters, this approach should work.
More info
You have to de-structure the props object. In react the first argument is always the props object.