app*_*orc 11 javascript reactjs mobx mobx-react react-hooks
我是 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 };
Run Code Online (Sandbox Code Playgroud)
上面的客户端代码将产生错误“只能在函数组件的主体内部调用 Hooks”。所以也许我必须将行var dispatch = useUserDispatch()向上移动到被调用的组件request,并dispatch作为 props 传递给request. 我觉得这是不对的,不仅request被迫关心一些无意义的事情dispatch,而且这dispatch会蔓延到组件需要的任何地方request。
对于基于类的组件,this.state也不能解决这个问题,但至少我可以使用mobx。
那么还有其他一些理想的方法来解决这个问题吗?
我也是这个时候来的。长话短说,如果您想自己手动完成所有工作,您需要将 Redux 和 Thunk 与异步逻辑结合使用,如下面链接 [1] 中的示例详细描述。
[1] https://redux.js.org/tutorials/essentials/part-5-async-logic
还有另一种解决方案,它提供了异步 API 的开箱即用体验(可以与 OpenAPI 和 GraphQL 一起使用,处理请求,提供生命周期缓存等),包装来自 [1] 的内容及其称为RTK 查询[2]。
[2] https://redux-toolkit.js.org/rtk-query/overview
下图直观地解释了 [1] 过程..但我认为RTK 查询[2] 将所有内容包装在一个地方,并且可能是更好的解决方案。有一个快速入门指南 [3]。我会试一下 :-)
[3] https://redux-toolkit.js.org/tutorials/rtk-query/
是的,你必须使用 Redux 或 MobX 来解决这个问题。您必须isAuthenticated在 Redux 或 MobX 的全局状态中维护状态。然后执行一个可以命名为的操作,toggleAuthState并将其传递给子组件并从那里切换状态。
对于这种情况,您也可以使用功能组件。基于类的组件并不是强制使用 MobX 或 Redux。如果您维护 HOC 作为 a Container,那么您可以将操作和状态传递给子级。
我展示了一个使用容器作为 HOC 的示例:
// Container
import React from "react"
import * as actions from "../actions"
import ChildComponent from "../components/ChildComponent"
import { connect } from "react-redux"
import { bindActionCreators } from "redux"
const Container = props => <ChildComponent { ...props } />
const mapStateToProps = state => ({ ...state })
const mapDispatchToProps = dispatch => bindActionCreators(actions, dispatch)
export default connect(mapStateToProps, mapDispatchToProps)(Container)
Run Code Online (Sandbox Code Playgroud)
然后,ChildComponent您可以在需要时使用您的状态并调度操作。