用USECONTEXT的USEDUCER集成未正确更新

发布于 2025-02-10 09:26:24 字数 2702 浏览 1 评论 0原文

我学习与打字稿有关的本地反应。我目前正在尝试使用UserEducer funtion从“组件树”下方的组件中消耗上下文。还原器似乎工作正常,返回预期值,但是上下文根本不会更新。 我一直在遵循一门课程,此确切的代码似乎对老师有用。我不知道我的错误可能在哪里。

这是我的代码:

authcontext.tsx

export interface AuthState {
  isLoggedIn: boolean;
  userName?: string;
  favoriteIcon?: string;
}

const authInit: AuthState = {
  isLoggedIn: false,
};

export interface AuthContextProps {
  authState: AuthState;
  signIn: () => void;
}
export const AuthContext = createContext({} as AuthContextProps);

export const AuthProvider = ({
  children,
}: {
  children: JSX.Element | JSX.Element[];
}) => {
  const [authState, dispatch] = useReducer(authReducer, authInit);

  const signIn = () => {
    dispatch({type: 'signIn'});
  };

  return (
    <AuthContext.Provider
      value={{
        authState: authInit,
        signIn,
      }}>
      {children}
    </AuthContext.Provider>
  );
};

authreducer.tsx

interface AuthAction {
  type: 'signIn';
}

export function authReducer(state: AuthState, action: AuthAction): AuthState {
  switch (action.type) {
    case 'signIn':
      let newstate = {
        ...state,
        isLoggedIn: true,
        userName: 'marrkoz',
      };
      //this console.log is running okay
      console.log(newstate);
      return newstate;
      break;
    default:
      return state;
  }
}

app.jsx

const App = () => {
  return (
    <NavigationContainer>
      <AppState>
        <BottomTabsNavigator />
      </AppState>
    </NavigationContainer>
  );
};

// i dont understand why this wrapper is necesary...
const AppState = ({children}: {children: JSX.Element | JSX.Element[]}) => {
  return <AuthProvider>{children}</AuthProvider>;
};

export default App;

在这里,我尝试每次消耗控制台按钮logs'{isloggedin:false}'。 组件层次结构是以下应用程序&gt;底部tabnavigator&gt; Toptabnavigator&gt; contacts.tsx

contacts.tsx


export const Contacts = () => {
  const {authState, signIn} = useContext(AuthContext);
  return (
    <>
      <View>
        <Text>Contacts</Text>
      </View>
      <View style={styles.m20}>
        <Button title={'sign in'} onPress={signIn} />
        <Button
          title={'console'}
          onPress={() => {
            console.log(JSON.stringify(authState));
          }}
        />
      </View>
    </>
  );
};

我唯一的猜测是,还原器返回值不链接到上下文,因此上下文不是“采用”新状态作为当前状态。如果是这样,我不知道如何解决

I`m learning React Native with Typescript. I'm currently trying to consume Context from components far down the "component tree" using useReducer funtion. The reducer seems to be working fine, returning the expected value, however the context doesn't update at all.
I've been following a course, and this exact code seems to work for the teacher. I have no idea where my error might be.

here's my code:

AuthContext.tsx

export interface AuthState {
  isLoggedIn: boolean;
  userName?: string;
  favoriteIcon?: string;
}

const authInit: AuthState = {
  isLoggedIn: false,
};

export interface AuthContextProps {
  authState: AuthState;
  signIn: () => void;
}
export const AuthContext = createContext({} as AuthContextProps);

export const AuthProvider = ({
  children,
}: {
  children: JSX.Element | JSX.Element[];
}) => {
  const [authState, dispatch] = useReducer(authReducer, authInit);

  const signIn = () => {
    dispatch({type: 'signIn'});
  };

  return (
    <AuthContext.Provider
      value={{
        authState: authInit,
        signIn,
      }}>
      {children}
    </AuthContext.Provider>
  );
};

AuthReducer.tsx

interface AuthAction {
  type: 'signIn';
}

export function authReducer(state: AuthState, action: AuthAction): AuthState {
  switch (action.type) {
    case 'signIn':
      let newstate = {
        ...state,
        isLoggedIn: true,
        userName: 'marrkoz',
      };
      //this console.log is running okay
      console.log(newstate);
      return newstate;
      break;
    default:
      return state;
  }
}

App.jsx

const App = () => {
  return (
    <NavigationContainer>
      <AppState>
        <BottomTabsNavigator />
      </AppState>
    </NavigationContainer>
  );
};

// i dont understand why this wrapper is necesary...
const AppState = ({children}: {children: JSX.Element | JSX.Element[]}) => {
  return <AuthProvider>{children}</AuthProvider>;
};

export default App;

Here i try consuming the console button logs '{isLoggedIn: false}' every single time.
the component hierarchy is the following App > BottomTabNavigator > TopTabNavigator > Contacts.tsx

Contacts.tsx


export const Contacts = () => {
  const {authState, signIn} = useContext(AuthContext);
  return (
    <>
      <View>
        <Text>Contacts</Text>
      </View>
      <View style={styles.m20}>
        <Button title={'sign in'} onPress={signIn} />
        <Button
          title={'console'}
          onPress={() => {
            console.log(JSON.stringify(authState));
          }}
        />
      </View>
    </>
  );
};

My only guess is that the reducer return value is somehow not linked with the context, therefore context is not "adopting" the new state as the current one. If thats the case, i have no idea how to solve it

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

殊姿 2025-02-17 09:26:24

在您的提供商中,您正在通过Authinit而不是Authstate。

请更改

value={{
        authState: authInit, // <---
        signIn,
      }}

value={{
        authState, // <---
        signIn,
      }}

In your provider, you're passing authInit instead of authState.

Please change

value={{
        authState: authInit, // <---
        signIn,
      }}

to

value={{
        authState, // <---
        signIn,
      }}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文