在react中使用recoil.js,在类组件中不使用钩子



我是反冲新手,我正在使用所有类组件。这是我的后坐力状态

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} />;
};

请注意:使用setRecoilStatesetRecoilCallback的主要区别在于,使用setRecoilState会自动为消耗组件订阅原子更改,而setRecoilCallback不会订阅,因此可以避免一些渲染。

您可以在这个工作的CodeSandbox中找到这两种解决方案。正如您所看到的,一旦Login组件更新令牌,PrintToken组件就会重新正确渲染。

如果你需要更多帮助,请告诉我😊

解决方案1:

将根文件中的RecoilNexus调用为App.tsxindex.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} />
}

相关内容

  • 没有找到相关文章

最新更新