簡體   English   中英

反應 useContext 鈎子:上下文在頁面重新加載時變為 null

[英]React useContext hook: context becomes null on page reload

我有以下 UserContext.js 文件,它將當前登錄的用戶存儲到用戶 object 和設置器 function 中。 在我的配置文件組件中,我想使用當前登錄用戶的信息預先填充我的輸入字段,我應該使用 useContext 掛鈎來獲取這些信息。

如果我從主頁正常導航到個人資料頁面,該應用程序工作正常,但是當我嘗試在個人資料頁面中直接訪問 /profile 或重新加載頁面時,我看到我的上下文在一瞬間變得未定義(如所見由console.log),在它加載一個值之前。 這會導致 useEffect() 鈎子和 initializeFields() function 失敗,因為屬性是 null。

我想要發生的是能夠無縫加載當前登錄的用戶,並在應用程序的其他組件中全局使用它。 將父組件中的用戶 object 作為 props 傳遞是不可行的,因為實際上,我的應用程序有一些組件很深,並且 prop-drilling 不是一個非常優雅的解決方案。

const UserContext = React.createContext({
  user: {},
  setUser: (user) => {},
});

在 App.js 組件中:

const App = (props) => {
  const [user, setUser] = useState(null);

  return (
    <div className="app">
      <UserContext.Provider value={{ user, setUser }}>
        <Switch>
          <Route path="/profile" exact component={Profile} />
        </Switch>      
      </UserContext.Provider>
    </div>
  );

Profile.js 組件:

const DashboardProfileModal = (props) => {
  const userContext = useContext(UserContext);
  const [name, setName] = useState();
  const [username, setUsername] = useState();
  const [password, setPassword] = useState();
  const [address, setAddress] = useState();

  console.log(userContext)

  useEffect(() => {
    initializeFields();
  });

  const initializeFields = () => {
    setName(userContext.user.name);
    setUsername(userContext.user.username);
    setPassword(userContext.user.password);
    setAddress(userContext.user.address);
  };

我相信您面臨的問題是因為您在App組件上聲明了提供程序。 如果您希望整個應用程序可以全局訪問它,您應該將它放在index.js文件中,並包裝App組件。 就像是:

ReactDOM.render(
  <React.StrictMode>
    <UserContext.Provider>
        <App />
    </UserContext.Provider>
  </React.StrictMode>,
  document.getElementById("root")
)

您可以執行以下操作,並在嘗試使用之前確保 userContext 可用。

您還應該至少通過添加[]使useEffect在頁面加載時運行一次(否則它會在每次渲染時不斷觸發)。 我還將userContext添加為useEffect的依賴項,然后檢查userContextname 這意味着它將確保userContext在嘗試運行您的方法之前不是null

然后我還包括!name檢查,以便我們可以確保在首次設置 state 后它不會繼續嘗試運行您的方法。

const DashboardProfileModal = (props) => {
  const userContext = useContext(UserContext);
  const [name, setName] = useState();
  const [username, setUsername] = useState();
  const [password, setPassword] = useState();
  const [address, setAddress] = useState();

  console.log(userContext)

  useEffect(() => {
    if(userContext && !name){
      initializeFields();
    }
  },[userContext]);

  const initializeFields = () => {
    setName(userContext.user.name);
    setUsername(userContext.user.username);
    setPassword(userContext.user.password);
    setAddress(userContext.user.address);
  };

暫無
暫無

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

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