How come this happens ? I want to update the child component when the state of my parent component changes. But nothing is happening as expected. Can someone please help.
below is one demo with a function as a children following the same pattern of render props.
import { useState, useEffect, useMemo } from "react";
import PropTypes from "prop-types";
import "./App.css";
const Fetch = ({ url, children }) => {
const [state, setState] = useState({
loading: false,
data: null,
errors: null,
});
useEffect(() => {
setState({ ...state, loading: true });
fetch(url)
.then((response) => response.json())
.then((data) => setState({ ...state, data: data, loading: false }))
.catch((err) => setState({ ...state, error: err, loading: false }));
}, [url]);
const response = useMemo(() => {
return state;
}, [state]);
if (state.loading) return <div>loading ...</div>;
if (state.errors) return <div>Something went wrong ...</div>;
if (!state.data) return <div>Sorry, no results</div>;
return <div>{children({ response })}</div>;
};
Fetch.propTypes = {
url: PropTypes.string,
};
function List({ Search }) {
debugger;
return Search?.map((item) => <Item {...item} />);
}
function Item({ Title }) {
return <li className="list-group-item">{Title}</li>;
}
function App() {
return (
<Fetch url="http://www.omdbapi.com/?s=deadpool&apikey=158fe49">
{({ data }) => {
return (
<div className="list d-flex justify-content-center">
<ul className="list-group">
<List {...data} />
</ul>
</div>
);
}}
</Fetch>
);
}
export default App;
Does anyone know why and how to resolve this ?
The problem is in the Fetch
component. You probably meant return <div>{children(response)}</div>
, because return <div>{children({ response })}</div>
will call the render function with an object that has a key response
.
Additionally, when this is fixed, the List
component throws an error because Search?.map((item) => <Item {...item} />)
will return undefined
if Search
is falsy, which is not acceptable. Instead, you should return null
or false
.
function List({ Search }) {
return Search ? Search.map((item) => <Item {...item} />) : null;
}