簡體   English   中英

關於反應上下文和重新渲染組件的快速問題

[英]quick question about react context and rerendering components

我今天剛開始玩上下文,這是我的用戶上下文

import { createContext, useEffect, useState } from "react";
import axios from "axios";

export const userContext = createContext({});
const UserContext = ({ children }) => {
  const [user, setUser] = useState({});

  useEffect(() => {
    axios.get("/api/auth/user", { withCredentials: true }).then((res) => {
      console.log(res);
      setUser(res.data.user);
    });
  }, []);

  return <userContext.Provider value={user}>{children}</userContext.Provider>;
};

export default UserContext;

這就是我在需要當前登錄用戶的任何組件中使用它的方式

const user = useContext(userContext)

我的問題是,每當用戶登錄或注銷時,我都必須刷新頁面才能看到瀏覽器中的更改。 有什么方法可以在不需要重新加載的情況下做到這一點。 也感謝任何關於反應上下文的一般提示

(編輯)這就是我使用 UserContext 的方式,如果它有幫助的話

const App = () => {
  return (
    <BrowserRouter>
      <UserContext>
        <Switch>
          {routes.map((route) => (
            <Route
              key={route.path}
              path={route.path}
              component={route.component}
            />
          ))}
        </Switch>
      </UserContext>
    </BrowserRouter>
  );
};

你的上下文消費者在哪里?

它的設置方式,任何以 UserContext 作為其祖先的 userContext.Consumer 都將在加載關聯用戶時重新呈現,而無需重新加載頁面。

為了更清楚,您應該將 UserContext 組件重命名為 UserProvider 並創建相應的 UserConsumer 組件:

import { createContext, useEffect, useState } from "react";
import axios from "axios";

export const userContext = createContext({});
const UserProvider = ({ children }) => {
    const [user, setUser] = useState({});

    useEffect(() => {
        axios.get("/api/auth/user", { withCredentials: true }).then((res) => {
        console.log(res);
        // setting the state here will trigger a re render of this component
            setUser(res.data.user);
        });
    }, []);

    return <userContext.Provider value={user}>{children}</userContext.Provider>;
};

const UserConsumer = ({ children }) => {
    return (
        <userContext.Consumer>
            {context => {
                if (context === undefined) {
                    throw new Error('UserConsumer must be used within a UserProvider ')
                }
                // children is assumed to be a function, it must be used
                // this way: context => render something with context (user)
                return children(context)
            }}
        </userContext.Consumer>
     );
};

export { UserProvider, UserConsumer };

使用示例:

import { UserConsumer } from 'the-file-containing-the-code-above';
export const SomeUiNeedingUserInfo = props => (
    <UserConsumer>
        {user => (
            <ul>
                <li>{user.firstName}</>
                <li>{user.lastName}</>
            </ul>
         )}
    </UserConsumer>
)

公平地說,您也可以自己注冊到上下文中,這種方式用於功能組件:

const AnotherConsumer = props => {
    const user = useContext(userContext);
    return (....);
}

對於 class 組件,這種方式:

class AnotherConsumer extends React.Component {
    static contextType = userContext;
    render() {
        const user = this.context;
        return (.....);
    }
}

UserConsumer 的好處是可重用性,而不必擔心您是否在功能或 class 組件中:它將以相同的方式使用。

無論哪種方式,您都必須“告訴”哪些組件注冊(應該偵聽)userContext 以使其在上下文更改時刷新。

這就是上下文的全部意義:允許渲染樹的一小部分受到影響並避免道具鑽孔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM