admin管理员组文章数量:1316511
const fetcher = (url: string) => fetch(url).then((r) => r.json());
const { data, error } = useSWR(
";,
fetcher,
);
is there any way to add data in a useState hook like this
const fetcher = (url: string) => fetch(url).then((r) => r.json());
const { data, error } = useSWR(
";,
fetcher,
);
const [memes,setMemes]=useState(data);
cause I want to concat the data at some point for inifnite scrolling
const fetcher = (url: string) => fetch(url).then((r) => r.json());
const { data, error } = useSWR(
"https://some./api",
fetcher,
);
is there any way to add data in a useState hook like this
const fetcher = (url: string) => fetch(url).then((r) => r.json());
const { data, error } = useSWR(
"https://meme-api.herokuapp./gimme/5",
fetcher,
);
const [memes,setMemes]=useState(data);
cause I want to concat the data at some point for inifnite scrolling
Share Improve this question asked Sep 27, 2021 at 11:09 Jatin HemnaniJatin Hemnani 3212 silver badges8 bronze badges 6-
Side note: Your
fetcher
function is falling prey to a footgun in thefetch
API I describe here. Before callingjson
, you probably want to check whether the HTTP request was successful (fetch
doesn't reject on HTTP errors, only network errors). So:const fetcher = (url: string) => fetch(url).then((r) => { if (!r.ok) { throw new Error(`HTTP error ${r.status}`); } return r.json(); });
– T.J. Crowder Commented Sep 27, 2021 at 11:18 -
1
FWIW,
useSWR
doesn't immediately seem to make sense with something likehttps://meme-api.herokuapp./gimme/5
that always provides a new set of responses when you send it a request. – T.J. Crowder Commented Sep 27, 2021 at 11:23 - You can but only when your ponent mounts, because you need to wait for the api response in useSWR(), add the data as dependency so whenever it changes, it'll rerender. – kmp Commented Sep 27, 2021 at 11:27
- @T.J.Crowder what if I want to contact the data every new request – Jatin Hemnani Commented Sep 27, 2021 at 13:52
- @JatinHemnani - What does "contact the data every new request" mean? – T.J. Crowder Commented Sep 27, 2021 at 13:55
2 Answers
Reset to default 5The fastest solution to transfer data from one variable to another is to use an useEffect
hook. When data
changes, update memes
.
useEffect(() => { setMemes(data); }, [data])
Infinite scroling
A better solution would be to use SWR provided solutions for infinite scrolling. You have different options documented here.
Plain fetch
In this case, you can also consider using directly the fetch function and appending data to the memes list directly:
const [ memes, setMemes ] = useState([]);
async function fetchAnotherPage() {
const data = (await fetch('https://meme-api.herokuapp./gimme/5')).json();
setMemes(value => [...value, ...data.memes]);
}
useEffect(() => fetchAnotherPage(), []);
Since https://meme-api.herokuapp./gimme/5
always returns new data for each call, useSWR
isn't a good fit for this and, moreover, the fact it retrieves from cache and gives that to your code and then revalidates and (possibly) calls your code to update, without telling you whether it's the first result or an update, makes it very hard to do what you're describing.
Instead, I'd just use fetch
directly and not try to do the SWR thing; see ments:
// Start with no memes
const [memes,setMemes] = useState([]);
// Use a ref to track an `AbortController` so we can:
// A) avoid overlapping fetches, and
// B) abort the current `fetch` operation (if any) on unmount
const fetchControllerRef = useRef(null);
// A function to fetch memes
const fetchMoreMemes = () => {
if (!fetchControllerRef.current) {
fetchControllerRef.current = new AbortController();
fetch("https://meme-api.herokuapp./gimme/5", {signal: fetchControllerRef.current.signal})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return response.json();
})
.then(newMemes => {
setMemes(memes => memes.concat(newMemes.memes));
})
.catch(error => {
// ...handle/report error...
})
.finally(() => {
fetchControllerRef.current = null;
});
}
};
// Fetch the first batch of memes
useEffect(() => {
fetchMoreMemes();
return () => {
// Cancel the current `fetch` (if any) when the ponent is unmounted
fetchControllerRef.current?.abort();
};
}, []);
When you want to fetch more memes, call fetchMoreMemes
.
Live Example:
const {useState, useEffect, useRef} = React;
const Example = () => {
// Start with no memes
const [memes,setMemes] = useState([]);
// Use a ref to track an `AbortController` so we can:
// A) avoid overlapping fetches, and
// B) abort the current `fetch` operation (if any) on unmount
const fetchControllerRef = useRef(null);
// A function to fetch memes
const fetchMoreMemes = () => {
if (!fetchControllerRef.current) {
fetchControllerRef.current = new AbortController();
fetch("https://meme-api.herokuapp./gimme/5", {signal: fetchControllerRef.current.signal})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return response.json();
})
.then(newMemes => {
// I'm filtering out NSFW ones here on SO
setMemes(memes => memes.concat(newMemes.memes.filter(({nsfw}) => !nsfw)));
})
.catch(error => {
// ...handle/report error...
})
.finally(() => {
fetchControllerRef.current = null;
});
}
};
// Fetch the first batch of memes
useEffect(() => {
fetchMoreMemes();
return () => {
// Cancel the current `fetch` (if any) when the ponent is unmounted
fetchControllerRef.current && fetchControllerRef.current.abort();
};
}, []);
const message = memes.length === 1 ? "1 meme:" : `${memes.length} memes:`;
return <div>
<div>{message} <input type="button" value="More" onClick={fetchMoreMemes}/></div>
<ul>
{/* `index` as key is ONLY valid because our array only grows */}
{memes.map(({postLink}, index) => <li key={index}>{postLink}</li>)}
</ul>
</div>
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare./ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>
本文标签: javascriptuse SWR data in useState HookStack Overflow
版权声明:本文标题:javascript - use SWR data in useState Hook - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741999715a2410760.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论