Я новичок в React, и когда я читал о документации, я обнаружил, что есть два способа реализации компонентов React: функциональный и классовый. Я знаю, что до React 16.8 невозможно управлять состоянием в функциональных компонентах, но после этого есть React Hooks.
Проблема в том, что, похоже, есть одно ограничение для React Hooks, их можно использовать только внутри функциональных составные части. В качестве примера возьмем сервер-клиент, которому необходимо изменить состояние isAuthenticated
при получении 401.
//client.js
import { useUserDispatch, signOut } from "auth";
export function request(url, args) {
var dispatch = useUserDispatch();
return fetch(url, args).then(response => {
if (response.status === 401) {
logout(dispatch);
}
}
);
//auth.js
import React from "react";
var UserStateContext = React.createContext();
var UserDispatchContext = React.createContext();
function userReducer(state, action) {
...
}
function UserProvider({ children }) {
var [state, dispatch] = React.useReducer(userReducer, {
isAuthenticated: false,
});
return (
<UserStateContext.Provider value={state}>
<UserDispatchContext.Provider value={dispatch}>
{children}
</UserDispatchContext.Provider>
</UserStateContext.Provider>
);
}
function useUserState() {
return React.useContext(UserStateContext);
}
function useUserDispatch() {
return React.useContext(UserDispatchContext);
}
function signOut(dispatch) {
dispatch({});
}
export { UserProvider, useUserState, useUserDispatch, loginUser, signOut };
Приведенный выше код клиента вызовет ошибку «Хуки могут быть вызваны только внутри тела функциональная составляющая ». Так что, возможно, мне нужно переместить строку var dispatch = useUserDispatch()
вверх в компонент, где вызывается request
, и передать dispatch
в качестве реквизита request
. Я считаю, что это неправильно, не только request
вынужден заботиться о каком-то бессмысленном (для него) dispatch
, но также этот dispatch
будет распространяться везде, где требуется компонент request
.
Для компонентов на основе классов this.state
тоже не решает эту проблему, но, по крайней мере, я могу использовать mobx.
Так есть ли другие идеальные способы решения этой проблемы?