Question: You are given the "MyComponent " functional component. You need to extract the functionality of this component into a function namely "useUserCollection" that will return 4 thing: {userCollection, loadUsers, filter, setFilter} And call that function from the functional component. Also, make sure the custom function call will be made only when the filter variable changes.
App.js
import React from "react";
export default function App () {
const [filter, setFilter] = React.useState("");
const [userCollection, setUserCollection] = React.useState([]);
//Load full list when the component gets mounted and filter gets updated
React.useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/users?name_like=${filter}`)
.then(response => response.json())
.then(json => setUserCollection(json));
}, [filter]);
return (
<div>
<input value={filter} onChange={e => setFilter(e.target.value)} />
<ul>
{userCollection.map((user, index) => (
<li key={index}>{user.name}</li>
))}
</ul>
</div>
);
};
What I have done
import React from "react";
export const useUserCollection = () => {
const [filter, setFilter] = React.useState("");
const [userCollection, setUserCollection] = React.useState([]);
function loadUsers () {
fetch(`https://jsonplaceholder.typicode.com/users?name_like=${filter}`)
.then(response => response.json())
.then(json => setUserCollection(json));
}
//Load full list when the component gets mounted and filter gets updated
React.useEffect(() => {
loadUsers();
}, [filter]);
return({userCollection, loadUsers, filter, setFilter});
}
export default function App () {
const {userCollection, loadUsers, filter, setFilter} = useUserCollection();
return (
<div>
<input value={filter} onChange={e => setFilter(e.target.value)} />
<ul>
{userCollection.map((user, index) => (
<li key={index}>{user.name}</li>
))}
</ul>
</div>
);
};
What warnings I am getting?
**How do I remove first warning? **
CodePudding user response:
Firstly you need to include the loadUsers
in the dependency array within useEffect
:
React.useEffect(() => {
loadUsers();
}, [loadUsers]);
Secondly, to avoid excessive re-renders (or even an endless loop), you will have to wrap the loadUsers
with useCallback
hook:
const loadUsers = useCallback(() => {
fetch(...);
}, [filter]);