it鈥榮 my first time to use this library. useSWR('/api/data', fetchData) will excute when App props changes. how can i use useEffect let it only work in componentDidMount..it seems not work in useEffect.
import useSWR from 'swr'
import fetchData from './fetch-data'
function App () {
const { data } = useSWR('/api/data', fetchData)
// ...
}`
expect
`import useSWR from 'swr'
import fetchData from './fetch-data'
function App () {
useEffect(() => {
const { data } = useSWR('/api/data', fetchData)
// ...
}, [])
}
You can't call hooks inside useEffect: https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
Instead you can do this:
function App () {
const [mounted, setMounted] = useState(false)
const { data } = useSWR(mounted ? '/api/data' : null, fetchData)
useEffect(() => {
setMounted(true)
}, [])
}
When key is null, SWR will pause itself. It's also explained here https://github.com/zeit/swr#key-as-a-function.
@quietshu Maybe I'm missing the intent here, but wouldn't fetch happen on every rerender this way? (since mounted is going to be always true)
@moroshko nope, SWR isn't like the normal fetch call. It will reuse the result, and only fetch again in certain cases by default (for example if you refocus on the window).
@shuding My fetched URL changes depending on some <select>. How does SWR handle that without useEffect?
That is... how can I accomplish something like below if I can't nest useSWR?
const [selectOption, setSelectOption] = useState()
useEffect(() => {
useSWR(`https://api.example.com/${selectOption}`) // 馃毃 can't nest hooks
}, [selectOption])
return (
<select>...</select>
)
@corysimmons you can just remove that useEffect:
const [selectOption, setSelectOption] = useState()
useSWR(`https://api.example.com/${selectOption}`)
return (
<select>...</select>
)
@shuding Awesome. btw I like your Github quote and domain name. Thanks for the nice library!
I'm having this same issue. I'm using the setMounted technique shown above. However, I still see network requests to my SWR endpoint when I change another property on the component and render gets called. Maybe SWR always makes the call in DEV mode?
If I add revalidateOnFocus: false to the SWR request then it seems to work. I'm testing this in Chrome developer tools. I wonder if it's doing something funky.
RevalidateOnFocus make SWR run a new fetch every time the tab recover focus, when you focus on the browser DevTools the tab lose focus, when you click again in the page it will recover the focus and revalidate the data triggering a new request.
Most helpful comment
You can't call hooks inside
useEffect: https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-levelInstead you can do this:
When
keyisnull, SWR will pause itself. It's also explained here https://github.com/zeit/swr#key-as-a-function.