对传递数组状态的 React Context API 有点困惑
A bit confuse about react ContextAPI passing an array state
代码已更新但问题仍然存在
我正在尝试在 React 本机应用程序中实现 React 上下文 API,我在 useEffect console.log 中有我的数据数组,但 .map 在 screen/not 上没有显示任何内容呈现任何错误。我不知道如何解决这个问题,所以我来这里寻求帮助。
这是我的 app.js 文件,我在其中创建上下文
import React, {useState} from 'react';
import { StyleSheet } from 'react-native';
import Page1 from './Page1';
export const BurgerContext = React.createContext()
export default function App() {
const [burgerDataBase,setBurgerDataBase] = useState([
{name:'Big Tasty', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Mac', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Tasty', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Mac', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Tasty', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Mac', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
])
return (
<BurgerContext.Provider value={{burgerDataBase, setBurgerDataBase}}>
<Page1/>
</BurgerContext.Provider>
);
}
这是我的 page1 屏幕,我想在其中获取数据表单上下文并在其上进行映射
import React, {useState, useEffect, useContext} from 'react'
import {BurgerContext} from './App'
import { Text,View } from 'react-native'
import styles from './styles'
export default function Page1() {
const [isLoading,setIsLoading] = useState(true)
const [page,setPage] = useState(1)
const {burgerDataBase} = useContext(BurgerContext)
useEffect(() => {
//change loading state after a settimeout function here
console.log('--------------------START OF BURGERBASE PAGE1-----------------------')
console.log(burgerDataBase) // i have my data as an array in my console here
console.log('---------------------END OF BURGERBASE PAGE1----------------------')
setTimeout(() => {
setIsLoading(false)
}, 1500);
}, [burgerDatabase])
const dataToShow = burgerDataBase.map(function(item,i){
<Text>{item.url}</Text>
})
if(isLoading){
return(
<View>
<Text>Loading ...</Text>
</View>
)
}
if(page === 1){
return (
<View style={styles.container}>
<View style={styles.page1body}>
<Text onPress={() => setPage(2)}>Go to Page 2.</Text>
{dataToShow}
</View>
</View>
)}
if(page === 2){
return(
<PageFav data={burgerDataBase}/>
)
}
}
App.js 具有固定上下文定义:
import React, { useState } from "react";
import Page1 from "./Page1";
export const BurgerContext = React.createContext();
export default function App() {
const [burgerDataBase, setBurgerDataBase] = useState([
{
name: "Big Tasty",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Mac",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Tasty",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Mac",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Tasty",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Mac",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
}
]);
return (
<BurgerContext.Provider value={{ burgerDataBase, setBurgerDataBase }}>
<Page1 />
</BurgerContext.Provider>
);
}
Page1.js(没有从“./styles”导入样式)
import React, { useState, useEffect, useContext } from "react";
import { BurgerContext } from "./App";
import { Text, View } from "react-native";
export default function Page1() {
const [isLoading, setIsLoading] = useState(true);
const [page, setPage] = useState(1);
const { burgerDataBase } = useContext(BurgerContext);
useEffect(() => {
//change loading state after a settimeout function here
console.log(
"--------------------START OF BURGERBASE PAGE1-----------------------"
);
console.log(burgerDataBase); // i have my data as an array in my console here
console.log(
"---------------------END OF BURGERBASE PAGE1----------------------"
);
setTimeout(() => {
setIsLoading(false);
}, 1500);
}, [burgerDataBase]);
const dataToShow = burgerDataBase.map((item, index) => (
<Text key={index}>{item.url}</Text>
));
if (isLoading) {
return (
<View>
<Text>Loading ...</Text>
</View>
);
}
if (page === 1) {
return (
<View>
<View>
<Text onPress={() => setPage(2)}>Go to Page 2.</Text>
{dataToShow}
</View>
</View>
);
}
}
你的 dataToShow 只被调用一次,当它第一次安装时显示加载。加载完成后,您设置为重新渲染项目,但仅当 burgerDatabase 发生变化时(在使用效果数组内)但 burgerDatabase 根本没有变化,因此渲染无法正常工作
像这样改变。
- 创建数组的空状态
- 将 burgerDatabase 存储在您在步骤 1 中创建的状态中,(在加载为假的超时内)
- 现在当 loading 设置为 false 时,那个时候 burger 新状态被设置并且它会重新呈现。
- 使用新创建的状态来呈现项目。
最终的解决方案是 return 地图内部的内容并且不要忘记在 useEffect [burgerDataBase] 中添加。两者结合使它起作用,谢谢大家!
代码已更新但问题仍然存在
我正在尝试在 React 本机应用程序中实现 React 上下文 API,我在 useEffect console.log 中有我的数据数组,但 .map 在 screen/not 上没有显示任何内容呈现任何错误。我不知道如何解决这个问题,所以我来这里寻求帮助。
这是我的 app.js 文件,我在其中创建上下文
import React, {useState} from 'react';
import { StyleSheet } from 'react-native';
import Page1 from './Page1';
export const BurgerContext = React.createContext()
export default function App() {
const [burgerDataBase,setBurgerDataBase] = useState([
{name:'Big Tasty', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Mac', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Tasty', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Mac', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Tasty', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
{name:'Big Mac', url:'https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg', price:'4.90',desc:'',brand:'Mc Donald'},
])
return (
<BurgerContext.Provider value={{burgerDataBase, setBurgerDataBase}}>
<Page1/>
</BurgerContext.Provider>
);
}
这是我的 page1 屏幕,我想在其中获取数据表单上下文并在其上进行映射
import React, {useState, useEffect, useContext} from 'react'
import {BurgerContext} from './App'
import { Text,View } from 'react-native'
import styles from './styles'
export default function Page1() {
const [isLoading,setIsLoading] = useState(true)
const [page,setPage] = useState(1)
const {burgerDataBase} = useContext(BurgerContext)
useEffect(() => {
//change loading state after a settimeout function here
console.log('--------------------START OF BURGERBASE PAGE1-----------------------')
console.log(burgerDataBase) // i have my data as an array in my console here
console.log('---------------------END OF BURGERBASE PAGE1----------------------')
setTimeout(() => {
setIsLoading(false)
}, 1500);
}, [burgerDatabase])
const dataToShow = burgerDataBase.map(function(item,i){
<Text>{item.url}</Text>
})
if(isLoading){
return(
<View>
<Text>Loading ...</Text>
</View>
)
}
if(page === 1){
return (
<View style={styles.container}>
<View style={styles.page1body}>
<Text onPress={() => setPage(2)}>Go to Page 2.</Text>
{dataToShow}
</View>
</View>
)}
if(page === 2){
return(
<PageFav data={burgerDataBase}/>
)
}
}
App.js 具有固定上下文定义:
import React, { useState } from "react";
import Page1 from "./Page1";
export const BurgerContext = React.createContext();
export default function App() {
const [burgerDataBase, setBurgerDataBase] = useState([
{
name: "Big Tasty",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Mac",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Tasty",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Mac",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Tasty",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
},
{
name: "Big Mac",
url:
"https://www.hamburgerfinder.fr/wp-content/uploads/McDonalds-Big-Tasty.jpg",
price: "4.90",
desc: "",
brand: "Mc Donald"
}
]);
return (
<BurgerContext.Provider value={{ burgerDataBase, setBurgerDataBase }}>
<Page1 />
</BurgerContext.Provider>
);
}
Page1.js(没有从“./styles”导入样式)
import React, { useState, useEffect, useContext } from "react";
import { BurgerContext } from "./App";
import { Text, View } from "react-native";
export default function Page1() {
const [isLoading, setIsLoading] = useState(true);
const [page, setPage] = useState(1);
const { burgerDataBase } = useContext(BurgerContext);
useEffect(() => {
//change loading state after a settimeout function here
console.log(
"--------------------START OF BURGERBASE PAGE1-----------------------"
);
console.log(burgerDataBase); // i have my data as an array in my console here
console.log(
"---------------------END OF BURGERBASE PAGE1----------------------"
);
setTimeout(() => {
setIsLoading(false);
}, 1500);
}, [burgerDataBase]);
const dataToShow = burgerDataBase.map((item, index) => (
<Text key={index}>{item.url}</Text>
));
if (isLoading) {
return (
<View>
<Text>Loading ...</Text>
</View>
);
}
if (page === 1) {
return (
<View>
<View>
<Text onPress={() => setPage(2)}>Go to Page 2.</Text>
{dataToShow}
</View>
</View>
);
}
}
你的 dataToShow 只被调用一次,当它第一次安装时显示加载。加载完成后,您设置为重新渲染项目,但仅当 burgerDatabase 发生变化时(在使用效果数组内)但 burgerDatabase 根本没有变化,因此渲染无法正常工作 像这样改变。
- 创建数组的空状态
- 将 burgerDatabase 存储在您在步骤 1 中创建的状态中,(在加载为假的超时内)
- 现在当 loading 设置为 false 时,那个时候 burger 新状态被设置并且它会重新呈现。
- 使用新创建的状态来呈现项目。
最终的解决方案是 return 地图内部的内容并且不要忘记在 useEffect [burgerDataBase] 中添加。两者结合使它起作用,谢谢大家!