mirror of
https://github.com/HackPlan/uui-admin-template.git
synced 2026-01-12 22:27:11 +08:00
recoil store
This commit is contained in:
@@ -32,8 +32,12 @@ module.exports = {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/camelcase": "off",
|
||||
"no-empty": "off",
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "warn",
|
||||
"react-hooks/exhaustive-deps": ["warn", {
|
||||
"additionalHooks": "useRecoilCallback"
|
||||
}],
|
||||
"react/display-name": "off"
|
||||
},
|
||||
"settings": {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "3.4.1",
|
||||
"recoil": "^0.0.10",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"typescript": "^3.9.6"
|
||||
},
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import React from 'react';
|
||||
import './App.css';
|
||||
import { AppRouter } from './routers/AppRouter';
|
||||
import { store } from './store';
|
||||
import { RecoilContainer } from './store/RecoilContainer';
|
||||
|
||||
function App() {
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<AppRouter />
|
||||
<RecoilContainer persistStates={[store.Auth]}>
|
||||
<AppRouter />
|
||||
</RecoilContainer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { TextField, Button } from '@hackplan/uui';
|
||||
import { useInject } from '../hooks/useInject';
|
||||
import { AuthApi } from '../api/AuthApi';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { store } from '../store';
|
||||
import useRouter from '../hooks/useRouter';
|
||||
|
||||
export function Login() {
|
||||
const { history } = useRouter()
|
||||
|
||||
const [username, setUsername] = useState('uui-template')
|
||||
const [password, setPassword] = useState('password')
|
||||
|
||||
const [auth, setAuth] = useRecoilState(store.Auth)
|
||||
useEffect(() => {
|
||||
if (auth && auth.token && auth.user) {
|
||||
history.push('/')
|
||||
}
|
||||
}, [auth, history])
|
||||
|
||||
const authApi = useInject(AuthApi)
|
||||
|
||||
return (
|
||||
@@ -24,7 +36,7 @@ export function Login() {
|
||||
</div>
|
||||
<Button className="w-full mt-4" onClick={async () => {
|
||||
const data = await authApi.login({ username, password })
|
||||
console.log(data)
|
||||
setAuth(data)
|
||||
}}>Login</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Route, RouteProps, Redirect } from 'react-router-dom';
|
||||
import { Redirect, Route, RouteProps } from 'react-router-dom';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { store } from '../store';
|
||||
|
||||
export const PublicRoute = Route;
|
||||
|
||||
export const AuthenticatedRoute = (props: RouteProps) => {
|
||||
// TODO: implement authenticated check
|
||||
if (false) {
|
||||
const isLogin = useRecoilValue(store.isLogin)
|
||||
if (!isLogin) {
|
||||
return (
|
||||
<Redirect
|
||||
to={{
|
||||
@@ -15,7 +17,6 @@ export const AuthenticatedRoute = (props: RouteProps) => {
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Route {...props} />
|
||||
)
|
||||
|
||||
41
src/store/RecoilContainer.tsx
Normal file
41
src/store/RecoilContainer.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import { RecoilRoot, useRecoilTransactionObserver_UNSTABLE, RecoilState } from 'recoil';
|
||||
|
||||
interface RecoilPersistProps {
|
||||
states: RecoilState<any>[];
|
||||
}
|
||||
function RecoilPersist(props: RecoilPersistProps) {
|
||||
useRecoilTransactionObserver_UNSTABLE(({ snapshot }) => {
|
||||
for (const state of props.states) {
|
||||
const { contents } = snapshot.getLoadable(state)
|
||||
localStorage.setItem(state.key, JSON.stringify(contents))
|
||||
}
|
||||
})
|
||||
return null
|
||||
}
|
||||
|
||||
export interface RecoilContainerProps {
|
||||
children: React.ReactNode;
|
||||
persistStates: RecoilPersistProps['states'];
|
||||
}
|
||||
export function RecoilContainer(props: RecoilContainerProps) {
|
||||
|
||||
return (
|
||||
<RecoilRoot initializeState={({ set }) => {
|
||||
for (const persistState of props.persistStates) {
|
||||
try {
|
||||
const data = localStorage.getItem(persistState.key)
|
||||
if (!data) continue
|
||||
const state = JSON.parse(data)
|
||||
set(persistState, state)
|
||||
} catch (error) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}}>
|
||||
<RecoilPersist states={props.persistStates} />
|
||||
{props.children}
|
||||
</RecoilRoot>
|
||||
)
|
||||
}
|
||||
|
||||
18
src/store/index.ts
Normal file
18
src/store/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { atom, selector } from 'recoil';
|
||||
import { UserAuth } from '../types/User';
|
||||
|
||||
const Auth = atom<UserAuth | null>({
|
||||
key: 'Auth',
|
||||
default: null,
|
||||
})
|
||||
const isLogin = selector<boolean>({
|
||||
key: 'isLogin',
|
||||
get: ({ get }) => {
|
||||
const auth = get(Auth)
|
||||
return !!auth && !!auth.user && !!auth.token
|
||||
}
|
||||
})
|
||||
|
||||
export const store = {
|
||||
Auth, isLogin,
|
||||
}
|
||||
10
src/types/User.ts
Normal file
10
src/types/User.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export interface User {
|
||||
name: string;
|
||||
avatar: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface UserAuth {
|
||||
token: string;
|
||||
user: User;
|
||||
}
|
||||
@@ -9356,6 +9356,11 @@ realpath-native@^1.1.0:
|
||||
dependencies:
|
||||
util.promisify "^1.0.0"
|
||||
|
||||
recoil@^0.0.10:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.0.10.tgz#679ab22306f559f8a63c46fd5ff5241539f9248f"
|
||||
integrity sha512-+9gRqehw3yKETmoZbhSnWu4GO10HDb5xYf1CjLF1oXGK2uT6GX5Lu9mfTXwjxV/jXxEKx8MIRUUbgPxvbJ8SEw==
|
||||
|
||||
recursive-readdir@2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f"
|
||||
|
||||
Reference in New Issue
Block a user