A bit confuse about react ContextAPI passing an array state - react-native

Code updated but still has the issue
I am trying to implement React Context API in a React native App, i have my array of data in the useEffect console.log but the .map not showing anything on screen/not rendering any error either. I'm out of idea to solve this problem so i come here for help.
this is my app.js file where i create the context
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>
);
}
this is my page1 screen where i want to get the data form context and map on them
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 with fixed Context definition:
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 (without import styles from './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>
);
}
}

Your dataToShow is called only one time, when it's first mounted that time loading was showing. after loading completed you set to re render item but only when there is change in burgerDatabase (inside array of use effect) but burgerDatabase is not changing at all so rendering is not working
change like this.
create empty state of array
store burgerDatabase in state which you created in step 1, (inside timeout where loading is false)
now when loading is set to false, that time burger new state is set and it will re render.
use newly created state to render items.

The final solution was to return what was inside the map and not forget to add inside the useEffect [burgerDataBase]. Both combined made it works , thx everyone !

Related

RTK Query why my data is showing null in console log?

Can anyone explain me why my data (todos) is null?
store.ts
import { createApi, fetchBaseQuery } from '#reduxjs/toolkit/query/react'
export interface Todo {
id: number;
text: string;
active: boolean;
done: boolean;
}
export const todoApi = createApi({
reducerPath: 'todoApi',
baseQuery: fetchBaseQuery({baseUrl: 'http://192.168.0.249:4000/'}),
tagTypes: ["Todos"],
endpoints: (builder) => ({
getAll: builder.query<Todo [], void>({
query: () => `todos`,
providesTags: [{ type: "Todos", id: "LIST" }]
})
})
})
App.tsx
import { ApiProvider } from '#reduxjs/toolkit/dist/query/react';
import { StatusBar } from 'expo-status-bar';
import { useEffect, useState } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';
import { todoApi } from './store/store';
const TodoApp = () => {
const { data: todos, isLoading, error } = todoApi.useGetAllQuery()
console.log(todos);
return (
<View style={styles.container}>
<Text>Hello</Text>
<Text>{ JSON.stringify(todos) }</Text>
</View>
)
}
export default function App() {
return (
<ApiProvider api={todoApi}>
<TodoApp />
</ApiProvider>
);
}
What I am doing wrong ?
................................................................................................................................................................

Card with FlatList React native

im trying to achieve message view by using card with flatlist how can i arrange few elements of my flat list the left screen right screen.
I want the green card to be on the left side of the screen
You can use react-native-gifted-chat for your desired result.
npm install react-native-gifted-chat --save
import React, { useState, useCallback, useEffect } from 'react'
import { GiftedChat } from 'react-native-gifted-chat'
export function Example() {
const [messages, setMessages] = useState([]);
useEffect(() => {
setMessages([
{
_id: 1,
text: 'Hello developer',
createdAt: new Date(),
user: {
_id: 2,
name: 'React Native',
avatar: 'https://placeimg.com/140/140/any',
},
},
])
}, [])
const onSend = useCallback((messages = []) => {
setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
}, [])
return (
<GiftedChat
messages={messages}
onSend={messages => onSend(messages)}
user={{
_id: 1,
}}
/>
)
}

Error trying to set up tabs in react-native

I need a hand to correct my code. I want to display a page with 3 tabs with react-native-tab-view and I don't know why I have an error. could you help me find where it's stuck?
What may seem obvious and easy to you may not be easy for me, so please be indulgent :) Thank you very much for your help and your time.
import * as React from 'react';
import { Dimensions } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
import Information from '../Information';
import Photos from '../Photos';
import Stock from '../Stock';
import { getProducts } from '../../../../src/common/Preferences';
import styles from '../../../../assets/styles';
import i18n from '../../../../src/i18n';
const FirstRoute = () => (
<Information style={styles.scene} />
);
const SecondRoute = () => (
<Stock style={styles.scene} />
);
const ThirdRoute = () => (
<Photos style={styles.scene} />
);
const initialLayout = { width: Dimensions.get('window').width };
export default class ProductDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
// productId: (props.navigation.state.params && props.navigation.state.params.productId ? props.navigation.state.params.productId : -1),
index: 0,
routes: [{ key: '1', title: i18n.t("information.title"),icon: 'ios-paper', }, {icon: 'ios-paper', key: '2', title: i18n.t("stock.title") }, {icon: 'ios-paper', key: '3', title: i18n.t("photos.title") }],
};
}
_handleIndexChange = index => {
this.setState({index})
};
_renderScene = SceneMap({
'1': FirstRoute,
'2': SecondRoute,
'3': ThirdRoute,
});
render() {
return (
<TabView
navigationState={this.state}
renderScene={this._renderScene}
initialLayout={initialLayout}
onRequestChangeTab={this._handleIndexChange}
useNativeDriver
/>
);
};
}
I get :
TypeError: _this.props.onIndexChange is not a function. (In
'_this.props.onIndexChange(index)', '_this.props.onIndexChange' is
undefined)

Invalid call at line 41: require(item.image)

I'm trying to create screen with a FlatList by using my component but why couldn't find the reason why i get error. I also checked React native dev website and see how FlatList works but still have no clue.
I'm pretty new at react native. Sorry if its very basic mistake.
The screen that im trying to create:
My component:
import React from "react";
import { Text, StyleSheet, View, TouchableOpacity, Image } from "react-native";
const ScreenMap = (props) => {
return (
<View>
<TouchableOpacity
onPress={props.path}>
<Image source={props.imageSource} />
</TouchableOpacity>
</View>);
};
const styles = StyleSheet.create({});
export default ScreenMap
Screen script:
import React from "react";
import { FlatList, Text, StyleSheet, View } from "react-native";
import ScreenMap from '../components/ScreenMap'
const BaslicaScreen = () => {
const contentButtons = [
{
title: "ilceler",
image:'../../assets/Baslica/ilceler.png'
},
{
title: "gururHuzurIlham",
image: '../../assets/Baslica/gururHuzurIlham.png'
},
{
title: "ulasim",
image:'../../assets/Baslica/ulasim.png'
},
{
title: "pratikBilgiler",
image:'../../assets/Baslica/pratikBilgiler.png'
},
{
title: "tarihiEserlerVeMuzeler",
image:'../../assets/Baslica/tarihiEserlerVeMuzeler.png'
},
{
title: "etkinlikler",
image: '../../assets/Baslica/etkinlikler.png'
},
{
title: "canakkaleyeOzgu",
image:'../../assets/Baslica/canakkaleyeOzgu.png'
},
]
return (<View style={styles.container}>
<FlatList
data={contentButtons}
keyExtractor={contButton => contButton.title}
renderItem={({ item }) => {
return <ScreenMap imageSource={require(item.image)} />
}}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "rgba(2,126,179,1)",
},
});
export default BaslicaScreen
Edit i fixed it by changin array to this:
const contentButtons = [
{
title: "ilceler",
image: require('../../assets/Baslica/ilceler.png')
},
{
title: "gururHuzurIlham",
image: require('../../assets/Baslica/gururHuzurIlham.png')
},
{
title: "ulasim",
image: require('../../assets/Baslica/ulasim.png')
},
{
title: "pratikBilgiler",
image: require('../../assets/Baslica/pratikBilgiler.png')
},
{
title: "tarihiEserlerVeMuzeler",
image: require('../../assets/Baslica/tarihiEserlerVeMuzeler.png')
},
{
title: "etkinlikler",
image: require('../../assets/Baslica/etkinlikler.png')
},
{
title: "canakkaleyeOzgu",
image: require('../../assets/Baslica/canakkaleyeOzgu.png')
},
]
and return this :
return <ScreenMap imageSource={item.image} />
you need to pass just image address and not object which is in require() form.
then put require(props.imageSource) inside of your ScreenMap and Image Component.

Tour view does not have React internal Fiber

I want implementation app-tour in my project , I installed react-native-app-tour .I have a View that I want assign app-tour to it and I use ref in view that it dispatch AppTourView to inputreducer and finally in useEffect I run appTour but when I run app I encountered Error that error is Tour view does not have React internal Fiber, please can help me
import React, {
useState,
useEffect,
useCallback,
useReducer,
useRef,
} from 'react';
import {AppTour, AppTourSequence, AppTourView} from 'react-native-app-tour';
const inputReducer = (state, action) => {
if (action.type == 'SET_APPTOUR') {
return [...state.appTour, action.data];
}
};
export default function HomeScreen(props) {
const [forsat, setForSat] = useState(null);
const [appTourTargets, dispatchAppTour] = useReducer(inputReducer, {
appTour: [],
});
useEffect(() => {
setTimeout(() => {
console.log(appTourTargets);
let appTourSequence = new AppTourSequence();
appTourTargets.appTour.forEach(appTourTarget => {
appTourSequence.add(appTourTarget);
});
AppTour.ShowSequence(appTourSequence);
}, 1000);
}, [appTourTargets]);
return(
<view style={styles.container}>
<View
ref={useCallback(ref => {
if (!ref) return;
setForSat(ref);
let prop = {
order: 12,
title: 'This is a target View',
description: 'We have the best targets, believe me',
outerCircleColor: '#3f52ae',
cancelable: false,
};
dispatchAppTour({type:'SET_APPTOUR', data:AppTourView.for(ref, {...prop})});
}, [])}
style={styles.rankContainer}>
<BText font="_Light" size={15} color={color.firstColor}>
فرصت{' '}
<BText font="_Bold" color={color.secondColor} size={15}>
{FormatHelper.toPersianString(daysToGo.toString())}
</BText>{' '}
روز تا کنکور
</BText>
</View>
</view>
)
}