在 React 中使用 Context API 和功能组件作为服务

Mor*_*emi 5 reactjs

我有一个上下文 API:

import React, { createContext, useState } from "react";

const UserContext = createContext();

const UserContextProvider = (props) => {
    const [userInfo, setUserInfo] = useState({});

    return (
        <UserContext.Provider value={{ userInfo, setUserInfo }}>
            {props.children}
        </UserContext.Provider>
    )
};

export { UserContextProvider, UserContext };
Run Code Online (Sandbox Code Playgroud)

并在 App.js 中使用它:

<UserContextProvider>
  // Router,...
</UserContextProvider>
Run Code Online (Sandbox Code Playgroud)

好吧,我将在组件中使用上下文 API,例如服务:

import { UserContext } from "...";

function UserService() {
    const { userInfo, setUserInfo } = useContext(UserContext);


    const updateUserInfo = (newUserInfo) => {
         setUserInfo(newUserInfo); // for example: {name:'x'}
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

现在我想UserService在组件内部使用而不添加<UserService />?我怎样才能打电话UserService.updateUserInfo()

小智 4

您不需要。userService您可以UserContext直接在内部使用App.js并访问其功能,但您必须将其包装App.js在内部UserContextProvider,如下所示:

<UserContextProvider>
   <App />
</UserContextProvider>
Run Code Online (Sandbox Code Playgroud)

或者你可以使用HOC(higher order component)像:

const withUsersContext = (Comp) => {
    return (props) => (
        <UserContextProvider>
            <Comp {...props} />
        </UserContextProvider>
    );
};

// then inside App.js:
...
export default withUsersContext(App)
Run Code Online (Sandbox Code Playgroud)

现在里面App.js

const { userInfo, setUserInfo } = useContext(UserContext);
Run Code Online (Sandbox Code Playgroud)

注意:如果你想UserContext在内部使用类似的东西,你必须为(react-hooks规则UserService)编写一个自定义钩子。UserService

定制挂钩UserService

function useUserService() {
    const { userInfo, setUserInfo } = useContext(UserContext);

    const updateUserInfo = (newUserInfo) => {
         setUserInfo(newUserInfo);
    }

    return { updateUserInfo };
}
Run Code Online (Sandbox Code Playgroud)

如何在组件内部使用:

...
const { updateUserInfo }= useUserService();
...
Run Code Online (Sandbox Code Playgroud)