繁体   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