Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the principle of swr in react.js?

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "what is the principle of swr in react.js". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "what is the principle of swr in react.js"?

What is swr

UseSWR is an interesting component of react hooks, which can be used not only as a request library but also as a cache for state management. The name SWR comes from "stale-while-revalidate" and is a cache update strategy proposed in the HTTP RFC 5861 standard:

First, take the data from the cache, and then request the corresponding data. Finally, compare the cache value with the latest value. If the cache value is the same as the latest value, you do not need to update it, otherwise update the cache with the latest value and update the UI display effect at the same time.

UseSWR can be used as a request library:

/ / fetchimport useSWR from 'swr'import fetch from' unfetch'const fetcher = url = > fetch (url). Then (r = > r.json ()) function App () {const {data, error} = useSWR ('/ api/data', fetcher) /.} / / axiosconst fetcher = url = > axios.get (url). Then (res = > res.data) function App () {const {data, error} = useSWR ('/ api/data') Fetcher) / / graphqlimport {request} from 'graphql-request'const fetcher = query = > request (' https://api.graph.cool/simple/v1/movies', query) function App () {const {data, error} = useSWR (`{Movie (title: "Inception") {releaseDate actors {name}}`, fetcher) / /.}

In addition, because the same key always returns the same instance, only one cache instance is saved in useSWR, so useSWR can also be used as a global state management machine. For example, you can save the user name globally:

Import useSWR from 'swr';function useUser (id: string) {const {data, error} = useSWR (`/ api/ user`, () = > {return {name:' yuxiaoliang', id,};}); return {user: data, isLoading:! error & &! data, isError: error,};} export default useUser

The specific use of swr is not the focus of this article, you can see the documentation, this article uses an example to lead to the understanding of the principle of swr:

Const sleep = async (times: number) = > {return new Promise (resolve = > {setTimeout () = > {resolve ();}, times);});}; const {data: data500} = useSWR ('/ api/user', async () = > {await sleep (500); return {a: '500 is ok'};}); const {data: data100} = useSWR (' / api/user', async () = > {await sleep Return {a: '100 is ok'};})

What is the output of data100 and data500 in the above code?

The answer is:

Both data100 and data500 output {aRom 500 is ok'}

The reason is also very simple. Within the default time of swr (default is 2000 milliseconds), for the key of the same useSWR, the key is'/ api/user' will be cleared, and only the fetcher function of the first key within 2000 milliseconds will update the cache.

With this example, let's take a closer look at the source code of swr

Second, the source code of swr

Let's start with useSWR's API and read the source code of swr. First of all, it is essentially an in-memory cache update strategy in swr, so the cached map is saved in the cache.ts file.

(1) cache.ts cache class Cache implements CacheInterface {constructor (initialData: any = {}) {this.__cache = new Map (Object.entries (initialData)) this.__listeners = []} get (key: keyInterface): any {const [_ key] = this.serializeKey (key) return this.__cache.get (_ key)} set (key: keyInterface) Value: any): any {const [_ key] = this.serializeKey (key) this.__cache.set (_ key, value) this.notify ()} keys () {} has (key: keyInterface) {} clear () {} delete (key: keyInterface) {} serializeKey (key: keyInterface): [string, any String] {let args = null if (typeof key = = 'function') {try {key = key ()} catch (err) {/ / dependencies not ready key ='}} if (Array.isArray (key)) {/ / args array args = key key = hash (key)} else {/ / convert null to'' Key = String (key | |')} const errorKey = key? 'err@' + key:' 'return [key, args, errorKey]} subscribe (listener: cacheListener) {if (typeof listener! = =' function') {throw new Error ('Expected the listener to be a function.')} let isSubscribed = true this.__listeners.push (listener) return () = > {/ / unsubscribe}} / / Notify Cache subscribers about a change in the cache private notify () {}

The above is the definition of the cache class, which is actually very simple. It maintains a map object with key as the index, where key can be a string, function or array. The method to serialize key is: serializeKey.

SerializeKey (key: keyInterface): [string, any String] {let args = null if (typeof key = = 'function') {try {key = key ()} catch (err) {/ / dependencies not ready key ='}} if (Array.isArray (key)) {/ / args array args = key key = hash (key)} else {/ / convert null to'' Key = String (key | |')} const errorKey = key? 'err@' + key:' 'return [key, args, errorKey]}

We can see from the definition of the above method:

If the key passed in is a string, then the string is the serialized key

If the key passed in is a function, then execute the function and the result is the serialized key

If the key passed in is an array, the serialized value is key via the hash method (similar to the hash algorithm, where the value of the array is serialized only).

In addition, in the cache class, save the cache object map, which stores the key and value information, in the instance object this.__cache, which is a map with set get and other methods.

(2) event handling

In swr, various events can be configured to trigger a corresponding re-request or update function when the event is triggered. Swr automatically updates the cache for these events, such as network disconnection, switching tab to refocus a tab, and so on.

The code for event handling in swr is:

Const revalidate = revalidators = > {if (! isDocumentVisible () | |! isOnline () return for (const key in revalidators) {if (revalidators [key] [0]) revalidators [key] [0] ()}} / / focus revalidate window.addEventListener ('visibilitychange', () = > revalidate (FOCUS_REVALIDATORS), false) window.addEventListener (' focus', () = > revalidate (FOCUS_REVALIDATORS), false) / reconnect revalidate window.addEventListener ('online') () = > revalidate (RECONNECT_REVALIDATORS), false)

The corresponding update cache function is saved in the above FOCUS_REVALIDATORS and RECONNECT_REVALIDATORS events. When the page triggers events such as visibilitychange (Show Hidden), focus (Page focus) and online (disconnected Network reconnection), the event is triggered and the cache is updated automatically.

(3) useSWR cache updated body function

UseSWR is the body function of swr, which determines how to cache and how to update. Let's first look at the input parameters and formal parameters of useSWR.

Input parameters:

Key: a unique value, which can be a string, function, or array, that uniquely identifies the key in the cache

Fetcher: (optional) function that returns data

Options: (optional) for some configuration items of useSWR, such as whether the event automatically triggers cache updates, etc.

Output parameters:

Data: the value value of the corresponding key in the cache corresponding to the input parameter key

Error: errors in the request process, etc.

IsValidating: whether it is requesting or updating the cache, it can be used as an identification such as isLoading.

Mutate (data?, shouldRevalidate?): update the function to update the value value of the corresponding key manually

From input parameters to output parameters, what we are essentially doing is to control the cache instance. The key to updating this map is:

When you need to take a value directly from the cache and when you need to re-request, update the value in the cache.

Const stateRef = useRef ({data: initialData, error: initialError, isValidating: false}) const CONCURRENT_PROMISES = {} / / with key as the key, value as the new value returned through functions such as fetch, const CONCURRENT_PROMISES_TS = {} / / with key as the key, value as the time stamp to start getting the new value by executing the function

Let's take a look at the core function of cache updates: revalidate

/ / start a revalidation const revalidate = useCallback (async (revalidateOpts= {}) = > {if (! key | |! fn) return false revalidateOpts= Object.assign ({dedupe: false}) RevalidateOpts) let loading = true let shouldDeduping = typeof CONCURRENT_ programs [key]! = 'undefined' & & revalidateOpts.dedupe / / start fetching try {dispatch ({isValidating: true}) let newData let startAt if (shouldDeduping) {startAt = CONCURRENT_PROMISES_ TS [key] newData = await CONCURRENT_ programs [key] ]} else {if (fnArgs! = = null) {CONCURRENT_ programs [key] = fn (... fnArgs)} else {CONCURRENT_ programs [key] = fn (key)} CONCURRENT_PROMISES_ TS [key] = startAt = Date.now () newData = await CONCURRENT_ programs [key] SetTimeout () = > {delete CONCURRENT_ programs [key] delete CONCURRENT_PROMISES_ TS [key]} Config.dedupingInterval)} const shouldIgnoreRequest = CONCURRENT_PROMISES_ TS [key] > startAt | | (MUTATION_ TS [key] & & (startAt so far) I believe you have a deeper understanding of "what is the principle of swr in react.js". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report