【问题标题】:useContext and useReducer Hooks not working. Error: Cannot read property 'state' of undefineduseContext 和 useReducer Hooks 不起作用。错误:无法读取未定义的属性“状态”
【发布时间】:2019-11-29 11:42:55
【问题描述】:

我正在尝试使用 createContext、useReducer 和 useContext 在 React Native 中实现 Redux 概念。以下是我的代码文件:

Store.tsx

import React, { useReducer, createContext } from "react";
import { View, Text, StyleSheet, Button } from "react-native";

export const myContext = createContext();

export default function Store(props) {
  const counter = 0;
  const [state, dispatch] = useReducer((state, action) => {
    return state + action;
  }, counter);
  return (
    <myContext.Provider value={{ state, dispatch }}>
      {props.children}
    </myContext.Provider>
  );
}

App.tsx

import React, { useState, useContext, useEffect, createContext } from            "react";
import { View, Text, StyleSheet, Button } from "react-native";
import Store, { myContext } from "./components/Store";

export default function App(): JSX.Element {
  const { state, dispatch } = useContext(myContext);

  return (
    <View style={styles.wrapper}>
      <Text>HEY</Text>
      <Store>
        <Text>Counter: {state}</Text>
        <Button title="Incr" onPress={() => dispatch(1)} />
        <Button title="Decr" onPress={() => dispatch(-1)} />
      </Store>
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    marginTop: 100
  }
});

我不确定为什么我无法在 useContex 中访问“状态”。我收到错误“无法读取未定义的属性“状态”” 请提供任何帮助。如果您也可以提供一些详细的解释,那将非常有帮助。

【问题讨论】:

    标签: reactjs typescript react-native react-hooks react-context


    【解决方案1】:

    您只能在上下文提供者的子组件中访问上下文的值。在这种情况下,您在 Store 中调用上面渲染 Provider 的 useContext。在这些情况下,会给出传递给 createContext 的默认值。在这种情况下,createContext(),没有给出默认值,所以它是未定义的。因此,尝试解构未定义的 const { state, dispatch } = useContext(myContext); 会导致您看到的错误。

    只需添加一个额外的子组件即可使其工作。比如:

    import React, { useState, useContext, useEffect, createContext } from            "react";
    import { View, Text, StyleSheet, Button } from "react-native";
    import Store, { myContext } from "./components/Store";
    
    export default function AppWrapper(): JSX.Element {
      // Store, renders the provider, so the context will be accessible from App.
      return (
        <Store>
          <App />
        </Store>
      )
    }
    
    function App(): JSX.Element {
      const { state, dispatch } = useContext(myContext);
    
      return (
        <View style={styles.wrapper}>
          <Text>HEY</Text>
          <Text>Counter: {state}</Text>
          <Button title="Incr" onPress={() => dispatch(1)} />
          <Button title="Decr" onPress={() => dispatch(-1)} />
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      wrapper: {
        marginTop: 100
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      相关资源
      最近更新 更多