我在使用 createContext() 和 useContext() 时做错了什么?

What do I do wrong when I use createContext(), and useContext()?

我可以在不使用 createContext() 和 useContext() 的情况下执行此操作。但是我想学习使用这个,所以我想添加useContext,和createContext。

通常我的 MainScreen.js

中有此代码
 const [users, setUsers] = useState([
        <HorizontalCircles skeleton={true} key={0} colorFirst={"rgb(" + 100 + "," + 100 + "," + 100 + ")"} colorSecond={"rgb(" + 100 + "," + 100 + "," + 100 + ")"}/>,
        <HorizontalCircles skeleton={true} key={1} colorFirst={"rgb(" + 100 + "," + 100 + "," + 100 + ")"} colorSecond={"rgb(" + 100 + "," + 100 + "," + 100 + ")"}/>,
    
      ])
    const getUsers = () => {
        // TODO: get discussion from SERVER
        // Dumy Data
        console.log("Getting Users");
    
        const tmpUsers = [];
    
        for (let i = 0; i < 1; i++) {
          const rand = Math.round(Math.random() * 255);
          const rand2 = Math.round(Math.random() * 255);
          const rand3 = Math.round(Math.random() * 255);
    
          tmpUsers.push(<HorizontalCircles key={i} colorFirst={"rgb(" + rand + "," + rand2 + "," + rand3 + ")"} colorSecond={"rgb(" + rand3 + "," + rand + "," + rand2 + ")"} />)
        }
        setTimeout(() => {
          setUsers(tmpUsers);
        }, 5000);
    
      }

由于我的 App.js 包含在导航中,我想我需要添加另一个文件,我可以在其中显示我的提供商。

这里是App.js

import 'react-native-gesture-handler';
import React from "react";
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import MainScreen from './src/components/screens/MainScreen';
import NewScreen from './src/components/screens/NewScreen';
import AnotherScreen from "./src/components/screens/AnotherScreen";


const Stack = createStackNavigator();

const App = () => {

  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home" screenOptions={{headerShown: false}}>
        <Stack.Screen name="Home" component={MainScreen} />
        <Stack.Screen name="NewScreen" component={NewScreen} />
        <Stack.Screen name="AnotherScreen" component={AnotherScreen} />        
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

这里是 App2.js 我包括提供者,

import React, { createContext,  } from "react";
import { View } from "react-native";
import MainScreen from "./src/components/screens/MainScreen";


export const UserContext = createContext();

function App2() {

  const [users, setUsers] = useState([
    <HorizontalCircles skeleton={true} key={0} colorFirst={"rgb(" + 100 + "," + 100 + "," + 100 + ")"} colorSecond={"rgb(" + 100 + "," + 100 + "," + 100 + ")"} />,
    <HorizontalCircles skeleton={true} key={1} colorFirst={"rgb(" + 100 + "," + 100 + "," + 100 + ")"} colorSecond={"rgb(" + 100 + "," + 100 + "," + 100 + ")"} />,

  ])
  return (
    <View className="App2">
      <UserContext.Provider value={users, setUsers}>
        <MainScreen />
      </UserContext.Provider>

    </View>
  )
}

这是 MainScreen.js 添加 App2.js

后唯一的变化
  const [users, setUsers] = useContext(UserContext);

我保留了相同的 getUsers() 函数。

我的错误是什么?没用,我只是想学习如何使用这个,我认为这应该有用,但它没有。

它给了我一个错误,说: 解构不可迭代实例的无效尝试。为了成为可迭代的非数组对象,必须具有 Symbol.iterator 方法。

我得到的最后一个错误是:

您在将值赋给上下文时缺少数组。这就是为什么您收到错误消息的原因,您正在尝试一个数组,但事实并非如此。 所以

<UserContext.Provider value={users, setUsers}>

应该是

<UserContext.Provider value={[users, setUsers]}>

但是你也应该使用备忘录来避免不必要的更新

const context = useMemo(() => ([users, setUsers]), [users])
// ... code

<UserContext.Provider value={context}>

为了使组件能够访问上下文值,它需要使用 Provider 进行包装。

创建一个新文件。 UserContextManager

import React, {createContext} from 'react';

export const UserContext = createContext();

function UserContextManager(props) {
  const [users, setUsers] = useState([
    <HorizontalCircles
      skeleton={true}
      key={0}
      colorFirst={'rgb(' + 100 + ',' + 100 + ',' + 100 + ')'}
      colorSecond={'rgb(' + 100 + ',' + 100 + ',' + 100 + ')'}
    />,
    <HorizontalCircles
      skeleton={true}
      key={1}
      colorFirst={'rgb(' + 100 + ',' + 100 + ',' + 100 + ')'}
      colorSecond={'rgb(' + 100 + ',' + 100 + ',' + 100 + ')'}
    />,
  ]);

  return (
    <UserContext.Provider value={{users, setUsers}}>
      {props.children}
    </UserContext.Provider>
  );
}

export default UserContextManager;

在App.js

<UserContextManager>
<NavigationContainer>
<Stack.Navigator initialRouteName="Home" screenOptions={{headerShown: false}}>
  <Stack.Screen name="Home" component={MainScreen} />
  <Stack.Screen name="NewScreen" component={NewScreen} />
  <Stack.Screen name="AnotherScreen" component={AnotherScreen} />        
</Stack.Navigator>
</NavigationContainer>
</UserContextManager>

现在,通过上述更改,您的 MainScreen 将可以访问上下文值。

在您的 MainScreen.js 中导入 userContext

import { UserContext } from 'your path to UserContextManager';


const Mainscreen = () => {
const { users, setUsers } = useContext(UserContext); 
  
  .... 
}