我在使用 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);
....
}
我可以在不使用 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);
....
}