Chore: improve swr use

This commit is contained in:
Dreamacro 2020-08-16 00:34:15 +08:00
parent 6265c5adb1
commit 1c45cc16e6
5 changed files with 53 additions and 98 deletions

View File

@ -1,5 +1,4 @@
import React, { useMemo } from 'react'
import useSWR from 'swr'
import EE from '@lib/event'
import { useRound } from '@lib/hook'
import { Card, Header, Icon, Checkbox } from '@components'
@ -68,12 +67,10 @@ function ProxyGroups () {
}
function ProxyProviders () {
const { providers, update } = useProxyProviders()
const { providers } = useProxyProviders()
const { useTranslation } = useI18n()
const { t } = useTranslation('Proxies')
useSWR('providers', update)
return <>
{
providers.length !== 0 &&
@ -95,12 +92,9 @@ function ProxyProviders () {
function Proxies () {
const { proxies } = useProxy()
const { update: updateGeneral } = useGeneral()
const { useTranslation } = useI18n()
const { t } = useTranslation('Proxies')
useSWR('general', updateGeneral)
function handleNotitySpeedTest () {
EE.notifySpeedTest()
}
@ -144,9 +138,6 @@ function Proxies () {
}
export default function ProxyContainer () {
const { update: updateProxy } = useProxy()
useSWR('proxies', updateProxy)
return (
<div className="page">
<ProxyGroups />

View File

@ -1,6 +1,6 @@
import React, { useLayoutEffect } from 'react'
import React from 'react'
import { Header, Card, Row, Col } from '@components'
import { useI18n, useRule, useRuleProviders, useVersion } from '@stores'
import { useI18n, useRule, useRuleProviders } from '@stores'
import { FixedSizeList as List } from 'react-window'
import AutoSizer from 'react-virtualized-auto-sizer'
import useSWR from 'swr'
@ -8,17 +8,10 @@ import { Provider } from './Provider'
import './style.scss'
function RuleProviders () {
const { providers, update } = useRuleProviders()
const { premium } = useVersion()
const { providers } = useRuleProviders()
const { useTranslation } = useI18n()
const { t } = useTranslation('Rules')
useLayoutEffect(() => {
if (premium) {
update()
}
}, [premium])
return <>
{
providers.length !== 0 &&

View File

@ -25,11 +25,6 @@ export default function Settings () {
mixedProxyPort: 0
})
useEffect(() => {
fetchGeneral()
fetchClashXData()
}, [])
useEffect(() => {
set('socks5ProxyPort', general?.socksPort ?? 0)
set('httpProxyPort', general?.port ?? 0)
@ -81,10 +76,10 @@ export default function Settings () {
} = apiInfo
const { allowLan, mode } = general
const {
startAtLogin,
systemProxy
} = clashXData
const startAtLogin = clashXData?.startAtLogin ?? false
const systemProxy = clashXData?.systemProxy ?? false
const isClashX = clashXData?.isClashX ?? false
const proxyModeOptions = useMemo(() => {
const options = [
@ -108,7 +103,7 @@ export default function Settings () {
<span className="label">{t('labels.startAtLogin')}</span>
</Col>
<Col span={8} className="value-column">
<Switch disabled={!clashXData.isClashX} checked={startAtLogin} onChange={handleStartAtLoginChange} />
<Switch disabled={!clashXData?.isClashX} checked={startAtLogin} onChange={handleStartAtLoginChange} />
</Col>
</Col>
<Col span={12}>
@ -127,7 +122,7 @@ export default function Settings () {
</Col>
<Col span={8} className="value-column">
<Switch
disabled={!clashXData.isClashX}
disabled={!isClashX}
checked={systemProxy}
onChange={handleSetSystemProxy}
/>
@ -167,7 +162,7 @@ export default function Settings () {
</Col>
<Col span={8}>
<Input
disabled={clashXData.isClashX}
disabled={isClashX}
value={info.socks5ProxyPort}
onChange={socks5ProxyPort => set('socks5ProxyPort', +socks5ProxyPort)}
onBlur={handleSocksPortSave}
@ -182,7 +177,7 @@ export default function Settings () {
</Col>
<Col span={8}>
<Input
disabled={clashXData.isClashX}
disabled={isClashX}
value={info.httpProxyPort}
onChange={httpProxyPort => set('httpProxyPort', +httpProxyPort)}
onBlur={handleHttpPortSave}
@ -195,7 +190,7 @@ export default function Settings () {
</Col>
<Col span={8}>
<Input
disabled={clashXData.isClashX}
disabled={isClashX}
value={info.mixedProxyPort}
onChange={mixedProxyPort => set('mixedProxyPort', +mixedProxyPort)}
onBlur={handleMixedPortSave}
@ -210,8 +205,8 @@ export default function Settings () {
</Col>
<Col className="external-controller" span={10}>
<span
className={classnames({ 'modify-btn': !clashXData.isClashX })}
onClick={() => !clashXData.isClashX && setIdentity(false)}>
className={classnames({ 'modify-btn': !isClashX })}
onClick={() => !isClashX && setIdentity(false)}>
{`${externalControllerHost}:${externalControllerPort}`}
</span>
</Col>

View File

@ -20,11 +20,10 @@ export default function Sidebar (props: SidebarProps) {
const { routes } = props
const { useTranslation } = useI18n()
const { version, premium, update } = useVersion()
const { data: { isClashX }, update: updateClashXData } = useClashXData()
const { data } = useClashXData()
const { t } = useTranslation('SideBar')
useSWR('version', update)
useSWR('clashx', updateClashXData)
const navlinks = routes.map(
({ path, name, exact, noMobile }) => (
@ -41,7 +40,7 @@ export default function Sidebar (props: SidebarProps) {
{ navlinks }
</ul>
<div className="sidebar-version">
<span className="sidebar-version-label">Clash{ isClashX && 'X' } { t('Version') }</span>
<span className="sidebar-version-label">Clash{ data?.isClashX && 'X' } { t('Version') }</span>
<span className="sidebar-version-text">{ version }</span>
{ premium && <span className="sidebar-version-label">Premium</span> }
</div>

View File

@ -1,8 +1,8 @@
import { atom, useRecoilState, selector } from 'recoil'
import get from 'lodash/get'
import throttle from 'lodash/throttle'
import { useCallback } from 'react'
import { useCallback, useEffect } from 'react'
import { AxiosError } from 'axios'
import swr from 'swr'
import { getLanguage, setLanguage, Lang, locales, Language } from '@i18n'
import { useRecoilObjectWithImmer } from '@lib/recoil'
@ -108,59 +108,43 @@ export const proxyProvider = atom({
})
export function useProxyProviders () {
const [data, set] = useRecoilState(proxyProvider)
const [providers, set] = useRecoilState(proxyProvider)
async function update () {
const { data, mutate } = swr('/providers/proxy', async () => {
const proxyProviders = await API.getProxyProviders()
const providers = Object.keys(proxyProviders.data.providers)
return Object.keys(proxyProviders.data.providers)
.map<API.Provider>(name => proxyProviders.data.providers[name])
.filter(pd => pd.name !== 'default')
.filter(pd => pd.vehicleType !== 'Compatible')
})
set(providers)
}
return { providers: data, update }
useEffect(() => set(data ?? []), [data, set])
return { providers, update: mutate }
}
export const ruleProvider = atom({
key: 'ruleProvider',
default: [] as API.RuleProvider[]
})
export function useRuleProviders () {
const [data, set] = useRecoilState(ruleProvider)
const [{ premium }] = useRecoilState(version)
async function update () {
const { data, mutate } = swr('/providers/rule', async () => {
if (!premium) {
return
return []
}
const ruleProviders = await API.getRuleProviders()
const providers = Object.keys(ruleProviders.data.providers)
return Object.keys(ruleProviders.data.providers)
.map<API.RuleProvider>(name => ruleProviders.data.providers[name])
})
set(providers)
}
return { providers: data, update }
return { providers: data ?? [], update: mutate }
}
export const general = atom({
key: 'general',
default: {} as Models.Data['general']
})
export function useGeneral () {
const [data, set] = useRecoilState(general)
async function update () {
const { data, mutate } = swr('/config', async () => {
const resp = await API.getConfig()
const data = resp.data
set({
return {
port: data.port,
socksPort: data['socks-port'],
mixedPort: data['mixed-port'] ?? 0,
@ -168,10 +152,10 @@ export function useGeneral () {
mode: data.mode.toLowerCase() as Models.Data['general']['mode'],
logLevel: data['log-level'],
allowLan: data['allow-lan']
} as Models.Data['general']
})
}
return { general: data, update: throttle(update, 50) }
return { general: data ?? {} as Models.Data['general'], update: mutate }
}
export const proxies = atom({
@ -184,9 +168,9 @@ export const proxies = atom({
})
export function useProxy () {
const [data, set] = useRecoilObjectWithImmer(proxies)
const [allProxy, set] = useRecoilObjectWithImmer(proxies)
async function update () {
const { data, mutate } = swr('/proxies', async () => {
const allProxies = await API.getProxies()
const global = allProxies.data.proxies.GLOBAL as API.Group
@ -199,15 +183,15 @@ export function useProxy () {
.filter(key => !unUsedProxy.has(key))
.map(key => ({ ...allProxies.data.proxies[key], name: key }))
const [proxy, groups] = partition(proxies, proxy => !policyGroup.has(proxy.type))
set({ proxies: proxy as API.Proxy[], groups: groups as API.Group[], global: global })
}
return { proxies: proxy as API.Proxy[], groups: groups as API.Group[], global: global }
})
useEffect(() => data && set(data), [data, set])
return {
proxies: data.proxies,
groups: data.groups,
global: data.global,
update,
proxies: allProxy.proxies,
groups: allProxy.groups,
global: allProxy.global,
update: mutate,
set
}
}
@ -232,30 +216,23 @@ export const proxyMapping = selector({
}
})
export const clashxData = atom({
key: 'clashxData',
default: {
export function useClashXData () {
const { data, mutate } = swr('/clashx', async () => {
if (!isClashX()) {
return {
isClashX: false,
startAtLogin: false,
systemProxy: false
}
})
export function useClashXData () {
const [data, set] = useRecoilState(clashxData)
async function update () {
if (!isClashX()) {
return
}
const startAtLogin = await jsBridge?.getStartAtLogin() ?? false
const systemProxy = await jsBridge?.isSystemProxySet() ?? false
set({ startAtLogin, systemProxy, isClashX: true })
}
return { startAtLogin, systemProxy, isClashX: true }
})
return { data, update }
return { data, update: mutate }
}
export const apiData = atom({