Custom React `useFetch` hook - do I need to maintain multiple states?
up vote
2
down vote
favorite
I've implemented a custom useFetch
hook so do fetching around my app:
import { useEffect, useState } from 'react'
const useFetch = ({ url, defaultData = null }) => {
const [data, setData] = useState(defaultData)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(res => {
setData(res)
setLoading(false)
})
.catch(err => {
setError(err)
setLoading(false)
})
}, )
return [data, loading, error]
}
export default useFetch
Then it occurred to me... this will be used all over the app. How will it know which data/loading/error belongs to what call? When I make use of useFetch
the first time, and then another use follows right behind it somewhere else in the app, does React track which internal state variables belong to which call of the hook?
Then I thought perhaps I need to do something more along the Redux lines and keep track of all the calls to the custom hook myself with the help of the useReducer
hook:
import { useEffect, useReducer } from 'react'
const reducer = (state, action) => {
const { url, data, err } = action
const currentState = state[url]
switch (action.type) {
case 'fetching':
return { ...state, [url]: { ...currentState, loading: true } }
case 'success':
return { ...state, [url]: { ...currentState, loading: false, data } }
case 'fail':
return { ...state, [url]: { ...currentState, loading: false, err } }
default:
return state
}
}
const useFetch = ({ url, defaultData = null }) => {
const [state, dispatch] = useReducer(reducer, {}, { type: 'fetching', url })
const { data: d, loading: l, err: e } = state[url]
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => dispatch({ type: 'success', url, data }))
.catch(err => dispatch({ type: 'fail', err }))
}, )
return [d || defaultData, l, e]
}
export default useFetch
Do I need to manually keep track of all the calls to useFetch
myself as in the 2nd example? Or does React handle this in its internals and the 1st example is all I need?
reactjs fetch react-hooks
add a comment |
up vote
2
down vote
favorite
I've implemented a custom useFetch
hook so do fetching around my app:
import { useEffect, useState } from 'react'
const useFetch = ({ url, defaultData = null }) => {
const [data, setData] = useState(defaultData)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(res => {
setData(res)
setLoading(false)
})
.catch(err => {
setError(err)
setLoading(false)
})
}, )
return [data, loading, error]
}
export default useFetch
Then it occurred to me... this will be used all over the app. How will it know which data/loading/error belongs to what call? When I make use of useFetch
the first time, and then another use follows right behind it somewhere else in the app, does React track which internal state variables belong to which call of the hook?
Then I thought perhaps I need to do something more along the Redux lines and keep track of all the calls to the custom hook myself with the help of the useReducer
hook:
import { useEffect, useReducer } from 'react'
const reducer = (state, action) => {
const { url, data, err } = action
const currentState = state[url]
switch (action.type) {
case 'fetching':
return { ...state, [url]: { ...currentState, loading: true } }
case 'success':
return { ...state, [url]: { ...currentState, loading: false, data } }
case 'fail':
return { ...state, [url]: { ...currentState, loading: false, err } }
default:
return state
}
}
const useFetch = ({ url, defaultData = null }) => {
const [state, dispatch] = useReducer(reducer, {}, { type: 'fetching', url })
const { data: d, loading: l, err: e } = state[url]
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => dispatch({ type: 'success', url, data }))
.catch(err => dispatch({ type: 'fail', err }))
}, )
return [d || defaultData, l, e]
}
export default useFetch
Do I need to manually keep track of all the calls to useFetch
myself as in the 2nd example? Or does React handle this in its internals and the 1st example is all I need?
reactjs fetch react-hooks
1
Custom hooks are for sharing stateful logic, not state. So something along the lines of your first snippet would work just fine.
– Tholle
Nov 19 at 20:27
1
@Tholle Good point. I guess it's hard breaking old habits!
– The Qodesmith
Nov 19 at 20:38
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I've implemented a custom useFetch
hook so do fetching around my app:
import { useEffect, useState } from 'react'
const useFetch = ({ url, defaultData = null }) => {
const [data, setData] = useState(defaultData)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(res => {
setData(res)
setLoading(false)
})
.catch(err => {
setError(err)
setLoading(false)
})
}, )
return [data, loading, error]
}
export default useFetch
Then it occurred to me... this will be used all over the app. How will it know which data/loading/error belongs to what call? When I make use of useFetch
the first time, and then another use follows right behind it somewhere else in the app, does React track which internal state variables belong to which call of the hook?
Then I thought perhaps I need to do something more along the Redux lines and keep track of all the calls to the custom hook myself with the help of the useReducer
hook:
import { useEffect, useReducer } from 'react'
const reducer = (state, action) => {
const { url, data, err } = action
const currentState = state[url]
switch (action.type) {
case 'fetching':
return { ...state, [url]: { ...currentState, loading: true } }
case 'success':
return { ...state, [url]: { ...currentState, loading: false, data } }
case 'fail':
return { ...state, [url]: { ...currentState, loading: false, err } }
default:
return state
}
}
const useFetch = ({ url, defaultData = null }) => {
const [state, dispatch] = useReducer(reducer, {}, { type: 'fetching', url })
const { data: d, loading: l, err: e } = state[url]
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => dispatch({ type: 'success', url, data }))
.catch(err => dispatch({ type: 'fail', err }))
}, )
return [d || defaultData, l, e]
}
export default useFetch
Do I need to manually keep track of all the calls to useFetch
myself as in the 2nd example? Or does React handle this in its internals and the 1st example is all I need?
reactjs fetch react-hooks
I've implemented a custom useFetch
hook so do fetching around my app:
import { useEffect, useState } from 'react'
const useFetch = ({ url, defaultData = null }) => {
const [data, setData] = useState(defaultData)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(res => {
setData(res)
setLoading(false)
})
.catch(err => {
setError(err)
setLoading(false)
})
}, )
return [data, loading, error]
}
export default useFetch
Then it occurred to me... this will be used all over the app. How will it know which data/loading/error belongs to what call? When I make use of useFetch
the first time, and then another use follows right behind it somewhere else in the app, does React track which internal state variables belong to which call of the hook?
Then I thought perhaps I need to do something more along the Redux lines and keep track of all the calls to the custom hook myself with the help of the useReducer
hook:
import { useEffect, useReducer } from 'react'
const reducer = (state, action) => {
const { url, data, err } = action
const currentState = state[url]
switch (action.type) {
case 'fetching':
return { ...state, [url]: { ...currentState, loading: true } }
case 'success':
return { ...state, [url]: { ...currentState, loading: false, data } }
case 'fail':
return { ...state, [url]: { ...currentState, loading: false, err } }
default:
return state
}
}
const useFetch = ({ url, defaultData = null }) => {
const [state, dispatch] = useReducer(reducer, {}, { type: 'fetching', url })
const { data: d, loading: l, err: e } = state[url]
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => dispatch({ type: 'success', url, data }))
.catch(err => dispatch({ type: 'fail', err }))
}, )
return [d || defaultData, l, e]
}
export default useFetch
Do I need to manually keep track of all the calls to useFetch
myself as in the 2nd example? Or does React handle this in its internals and the 1st example is all I need?
reactjs fetch react-hooks
reactjs fetch react-hooks
edited Nov 23 at 5:47
Jagrati
2,61021429
2,61021429
asked Nov 19 at 20:24
The Qodesmith
96211329
96211329
1
Custom hooks are for sharing stateful logic, not state. So something along the lines of your first snippet would work just fine.
– Tholle
Nov 19 at 20:27
1
@Tholle Good point. I guess it's hard breaking old habits!
– The Qodesmith
Nov 19 at 20:38
add a comment |
1
Custom hooks are for sharing stateful logic, not state. So something along the lines of your first snippet would work just fine.
– Tholle
Nov 19 at 20:27
1
@Tholle Good point. I guess it's hard breaking old habits!
– The Qodesmith
Nov 19 at 20:38
1
1
Custom hooks are for sharing stateful logic, not state. So something along the lines of your first snippet would work just fine.
– Tholle
Nov 19 at 20:27
Custom hooks are for sharing stateful logic, not state. So something along the lines of your first snippet would work just fine.
– Tholle
Nov 19 at 20:27
1
1
@Tholle Good point. I guess it's hard breaking old habits!
– The Qodesmith
Nov 19 at 20:38
@Tholle Good point. I guess it's hard breaking old habits!
– The Qodesmith
Nov 19 at 20:38
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
Each custom hook will have its own state and will not share state among different instances of the same hook. Hence you don't need to keep track of which state belongs to which hook.
Hooks will only share the logic and not data among different instances, much like HOCs and Render Props
.
So the first example would work just right.
In your case multiple calls to useFetch
will essentially lead to multiple calls to useState
and React FAQs explain the independence of state with useState
which does indeed answer your doubt
React keeps track of the currently rendering component. Thanks to the
Rules of Hooks, we know that Hooks are only called from React
components (or custom Hooks — which are also only called from React
components).
There is an internal list of “memory cells” associated with each
component. They’re just JavaScript objects where we can put some data.
When you call a Hook like useState(), it reads the current cell (or
initializes it during the first render), and then moves the pointer to
the next one. This is how multiple useState() calls each get
independent local state.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Each custom hook will have its own state and will not share state among different instances of the same hook. Hence you don't need to keep track of which state belongs to which hook.
Hooks will only share the logic and not data among different instances, much like HOCs and Render Props
.
So the first example would work just right.
In your case multiple calls to useFetch
will essentially lead to multiple calls to useState
and React FAQs explain the independence of state with useState
which does indeed answer your doubt
React keeps track of the currently rendering component. Thanks to the
Rules of Hooks, we know that Hooks are only called from React
components (or custom Hooks — which are also only called from React
components).
There is an internal list of “memory cells” associated with each
component. They’re just JavaScript objects where we can put some data.
When you call a Hook like useState(), it reads the current cell (or
initializes it during the first render), and then moves the pointer to
the next one. This is how multiple useState() calls each get
independent local state.
add a comment |
up vote
2
down vote
accepted
Each custom hook will have its own state and will not share state among different instances of the same hook. Hence you don't need to keep track of which state belongs to which hook.
Hooks will only share the logic and not data among different instances, much like HOCs and Render Props
.
So the first example would work just right.
In your case multiple calls to useFetch
will essentially lead to multiple calls to useState
and React FAQs explain the independence of state with useState
which does indeed answer your doubt
React keeps track of the currently rendering component. Thanks to the
Rules of Hooks, we know that Hooks are only called from React
components (or custom Hooks — which are also only called from React
components).
There is an internal list of “memory cells” associated with each
component. They’re just JavaScript objects where we can put some data.
When you call a Hook like useState(), it reads the current cell (or
initializes it during the first render), and then moves the pointer to
the next one. This is how multiple useState() calls each get
independent local state.
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Each custom hook will have its own state and will not share state among different instances of the same hook. Hence you don't need to keep track of which state belongs to which hook.
Hooks will only share the logic and not data among different instances, much like HOCs and Render Props
.
So the first example would work just right.
In your case multiple calls to useFetch
will essentially lead to multiple calls to useState
and React FAQs explain the independence of state with useState
which does indeed answer your doubt
React keeps track of the currently rendering component. Thanks to the
Rules of Hooks, we know that Hooks are only called from React
components (or custom Hooks — which are also only called from React
components).
There is an internal list of “memory cells” associated with each
component. They’re just JavaScript objects where we can put some data.
When you call a Hook like useState(), it reads the current cell (or
initializes it during the first render), and then moves the pointer to
the next one. This is how multiple useState() calls each get
independent local state.
Each custom hook will have its own state and will not share state among different instances of the same hook. Hence you don't need to keep track of which state belongs to which hook.
Hooks will only share the logic and not data among different instances, much like HOCs and Render Props
.
So the first example would work just right.
In your case multiple calls to useFetch
will essentially lead to multiple calls to useState
and React FAQs explain the independence of state with useState
which does indeed answer your doubt
React keeps track of the currently rendering component. Thanks to the
Rules of Hooks, we know that Hooks are only called from React
components (or custom Hooks — which are also only called from React
components).
There is an internal list of “memory cells” associated with each
component. They’re just JavaScript objects where we can put some data.
When you call a Hook like useState(), it reads the current cell (or
initializes it during the first render), and then moves the pointer to
the next one. This is how multiple useState() calls each get
independent local state.
edited Nov 20 at 5:11
answered Nov 20 at 5:05
Shubham Khatri
75.6k1385124
75.6k1385124
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382115%2fcustom-react-usefetch-hook-do-i-need-to-maintain-multiple-states%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Custom hooks are for sharing stateful logic, not state. So something along the lines of your first snippet would work just fine.
– Tholle
Nov 19 at 20:27
1
@Tholle Good point. I guess it's hard breaking old habits!
– The Qodesmith
Nov 19 at 20:38