我是反冲新手,我正在使用所有类组件。这是我的后坐力状态
export const tokenState = atom({
key: "tokenState",
default: "",
});
如何在类组件中使用反冲并设置令牌?我在应用程序中将RecoilRoot
用作
<RecoilRoot>
<Header />
<Main />
</RecoilRoot>
在login.js
中,我想将令牌设置为反冲,但login.js
是一个类组件。
const res = await APIS.login(apiRoute,requestObject);
在res.data.token
中,我得到了jwt令牌。
提前谢谢!
Recoil.JS旨在与react钩子一起使用,我认为它们除了钩子之外没有提供任何其他功能。如果您无法将Login.js更改为功能组件,请尝试使用包装功能组件,该组件将令牌作为道具传递给Login.js组件。
我建议useRecoilState(myAtom)
。
function LoginWrapper(props) {
const [token, setToken] = useRecoilState(myAtom);
useEffect(() => {
async function get() {
const { data: { token: jwt } } = await APIS.login(apiRoute,requestObject);
setToken(jwt);
}
get();
}, []);
return <LoginComponent {...props} jwt={token} />
}
正如@Matt所说,您必须将类组件包装成一个函数组件,该组件将Recoil API作为道具传递。
无论如何,如果您想从Login
组件中设置原子标记,您可以简单地将Login
封装到一个传递useSetRecoilState
结果的组件中
const LoginWrapper = () => {
const setToken = useSetRecoilState(tokenState);
return <Login setToken={setToken} />;
};
在更复杂的情况下,您可以利用Recoil’useRecoilCallback
,它允许您一次使用整个Recoil API
const LoginWrapper = () => {
const setToken = useRecoilCallback(({ set }) => token => {
set(tokenState, token);
});
return <Login setToken={setToken} />;
};
请注意:使用
setRecoilState
和setRecoilCallback
的主要区别在于,使用setRecoilState
会自动为消耗组件订阅原子更改,而setRecoilCallback
不会订阅,因此可以避免一些渲染。
您可以在这个工作的CodeSandbox中找到这两种解决方案。正如您所看到的,一旦Login
组件更新令牌,PrintToken
组件就会重新正确渲染。
如果你需要更多帮助,请告诉我😊
解决方案1:
将根文件中的RecoilNexus
调用为App.tsx
或index.tsx
return (
<RecoilNexus />
)
然后,您可以调用getRecoil
来获取反冲状态,调用setRecoil
来设置反冲状态
import {setRecoil, getRecoil, getRecoilPromise, resetRecoil} from '@components/RecoilNexus';
export const tokenState = atom({
key: "tokenState",
default: "",
});
const onSetTokenState=setRecoil(tokenState)
onSetTokenState("abc")
const tokenRecoilState=getRecoil(tokenState)
console.log(tokenRecoilState)
RecoilNexus.tsx
import {RecoilValue, RecoilState, useRecoilCallback} from 'recoil';
interface Nexus {
get?: <T>(atom: RecoilValue<T>) => T;
getPromise?: <T>(atom: RecoilValue<T>) => Promise<T>;
set?: <T>(
atom: RecoilState<T>,
valOrUpdater: T | ((currVal: T) => T),
) => void;
reset?: (atom: RecoilState<any>) => void;
}
const nexus: Nexus = {};
export default function RecoilNexus() {
nexus.get = useRecoilCallback<[atom: RecoilValue<any>], any>(
({snapshot}) =>
function <T>(atom: RecoilValue<T>) {
return snapshot.getLoadable(atom).contents;
},
[],
);
nexus.getPromise = useRecoilCallback<[atom: RecoilValue<any>], Promise<any>>(
({snapshot}) =>
function <T>(atom: RecoilValue<T>) {
return snapshot.getPromise(atom);
},
[],
);
nexus.set = useRecoilCallback(({set}) => set, []);
nexus.reset = useRecoilCallback(({reset}) => reset, []);
return null;
}
export function getRecoil<T>(atom: RecoilValue<T>): T {
return nexus.get!(atom);
}
export function getRecoilPromise<T>(atom: RecoilValue<T>): Promise<T> {
return nexus.getPromise!(atom);
}
export function setRecoil<T>(
atom: RecoilState<T>,
valOrUpdater: T | ((currVal: T) => T),
) {
nexus.set!(atom, valOrUpdater);
}
export function resetRecoil(atom: RecoilState<any>) {
nexus.reset!(atom);
}
解决方案2:
将功能组件包裹在类组件周围,并将反冲状态或设置器功能作为道具传递,如
function LoginCompnentWrapper(props) {
const [token, setToken] = useRecoilState(myAtom);
return <LoginComponent {...props} token={token} setToken={setToken} />
}