Error: `useTheme` must be used within `NativeBaseConfigProvider` - node.js

In my project I experienced the above error
The error explanation :
This error is located at:
in Container
in ProductContainer (created by App)
in RCTView (created by View)
in View (created by App)
in App (created by ExpoRoot)
in ExpoRoot
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
ProductContainer.js:
import React, { useState, useEffect } from 'react'
import { View, StyleSheet, ActivityIndicator, FlatList, Text} from 'react-native'
import { Container, Header, Icon, Item, Input, Text } from 'native-base';
import ProductList from './ProductList';
const data = require('../../assets/data/products.json');
const ProductContainer = () => {
const [products, setProducts ] = useState([]);
useEffect(() => {
setProducts(data);
return () => {
setProducts([])
}
}, [])
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}
})
return (
<Container>
<Header searchBar rounded>
</Header>
<View style={styles.container}>
<Text>Product Container</Text>
<View style={styles.listContainer}>
<FlatList
data={products}
numColumns={2}
renderItem={({item}) => <ProductList
key={item.brand}
item={item}/>}
keyExtractor={item => item.brand}
/>
</View>
</View>
</Container>
)
}
export default ProductContainer;

I managed to solve this error from this github issue: https://github.com/GeekyAnts/NativeBase/issues/4303.
Apparently the problem is that you need to wrap app elements in <NativeBaseProvider>.
In this example you can see how the native base provider wraps all other providers, if the <NativeBaseProvider> is not at the top, it will throw the error: useTheme must be used within `NativeBaseConfigProvider
export default function App() {
return (
<NativeBaseProvider>
<SafeAreaProvider>
<AuthProvider>
<Navigation colorScheme={colorScheme} />
<StatusBar />
</AuthProvider>
</SafeAreaProvider>
</NativeBaseProvider>
);
}

<Container>
<Header searchBar rounded>
</Header>
<View style={styles.container}>
<Text>Product Container</Text>
<View style={styles.listContainer}>
<FlatList
data={products}
numColumns={2}
renderItem={({item}) => <ProductList
key={item.brand}
item={item}/>}
keyExtractor={item => item.brand}
/>
</View>
</View>
</Container>
wrap all these Container tag and its contents inside...

If the issue is happening in Testing you can simply pass initialWindowMetrics to NativeBaseProvider in your tests.
const inset = {
frame: { x: 0, y: 0, width: 0, height: 0 },
insets: { top: 0, left: 0, right: 0, bottom: 0 },
};
<NativeBaseProvider initialWindowMetrics={inset}>
{children}
</NativeBaseProvider>;

Related

in react native how i can change background color for every view element independent

for every view element independent when i press them without effect other views and save pressed state so next time i can find what ipressed still pressed and i can change color of other view when ipress them without lose stat of preview view
the problem is when i press one from two task the other task also change her background color
import React, { useState } from 'react';
import {
SafeAreaView,
View,
FlatList,
StyleSheet,
Text,
TouchableOpacity,
} from 'react-native';
function App() {
const [changBack,backgroundColor]=useState('green')
function changIt() {
backgroundColor('red');
}
const DATA1 = 'Task one';
const DATA2 = 'Task two';
return (
<View>
<TouchableOpacity
style={{
flex: 1,
backgroundColor:changBack,
padding: 20,
}}
onPress={changIt}>
<View>
<Text>{DATA1}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{
flex: 1,
backgroundColor:changBack,
padding: 20,
}}
onPress={changIt}>
<View>
<Text>{DATA2}</Text>
</View>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection:'column',
textAlign:'right',
justifyContent:'space-evenly',
},
});
export default App;
Brother I notice you passed backgroundColor on Style for <TouchableOpacity> so definitely it won't work. backgroundColor is applicable for <View> only but not for TouchableOpcacity.
Do something like this ~
<View>
<View style={{backgroundColor:changBack}}>
<TouchableOpacity onPress={changeIt}>
<View>
<Text>Heyya</Text>
</View>
</ToucableOpacity>
</View>
</View>
or this,
<View>
<TouchableOpacity onPress={changeIt}>
<View style={{backgroundColor:changBack}}>
<Text>Heyya</Text>
</View>
</ToucableOpacity>
</View>

On my react-native app I'm getting Component Exception API call error of ' Text strings must be rendered within a <Text/>'

This is the react-native app, runs without errors when the API is not called, the errors only when I run the API created using NodeJs.
I'm getting the error as API call error
Text strings must be rendered within a component.
Below is the error shown in the console where I run the react-native app
Api call error
Error: Text strings must be rendered within a <Text> component.
This error is located at:
in RCTView (at View.js:34)
in View (at ProductContainer.js:125)
in RCTView (at View.js:34)
in View (at ScrollView.js:1124)
in RCTScrollView (at ScrollView.js:1260)
in ScrollView (at ScrollView.js:1286)
in ScrollView (at ProductContainer.js:124)
in RCTView (at View.js:34)
in View (at Container.js:12)
in Container (at connectStyle.js:392)
in Styled(Container) (at ProductContainer.js:104)
in ProductContainer (at SceneView.tsx:122)
in StaticContainer
in StaticContainer (at SceneView.tsx:115)
in EnsureSingleNavigator (at SceneView.tsx:114)
in SceneView (at useDescriptors.tsx:153)
in RCTView (at View.js:34)
in View (at CardContainer.tsx:245)
in RCTView (at View.js:34)
in View (at CardContainer.tsx:244)
in RCTView (at View.js:34)
in View (at CardSheet.tsx:33)
in ForwardRef(CardSheet) (at Card.tsx:573)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:165)
in AnimatedComponent (at createAnimatedComponent.js:215)
in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:555)
in PanGestureHandler (at GestureHandlerNative.tsx:13)
at node_modules\react-native\Libraries\LogBox\LogBox.js:148:8 in registerError
at node_modules\react-native\Libraries\LogBox\LogBox.js:59:8 in errorImpl
at node_modules\react-native\Libraries\LogBox\LogBox.js:33:4 in console.error
at node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:104:6 in reportException
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:171:19 in handleException
at node_modules\react-native\Libraries\Core\ReactFiberErrorDialog.js:43:2 in showErrorDialog
at node_modules\react-native\Libraries\Renderer\implementations\ReactNativeRenderer-dev.js:15258:32 in logCapturedError
at [native code]:null in dispatchAction
at Screens\Products\ProductContainer.js:44:10 in axios.get.then$argument_0
at node_modules\react-native\node_modules\promise\setimmediate\core.js:37:13 in tryCallOne
at node_modules\react-native\node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:130:14 in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:181:14 in _callImmediatesPass
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:441:30 in callImmediates
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:387:6 in __callImmediates
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:135:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:364:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:134:4 in flushedQueue
at [native code]:null in flushedQueue
at [native code]:null in callFunctionReturnFlushedQueue
Here is the screenShot of the error shown in the Mobile app
And Code shown in the error is
if (!hostContext.isInAParentText) {
throw Error("Text strings must be rendered within a <Text> component.");
}
Below provided is the ProductContainer.js Code
import React, { useState, useCallback } from "react";
import {
View,
StyleSheet,
ActivityIndicator,
FlatList,
ScrollView,
Dimensions,
} from "react-native";
import { Container, Header, Icon, Item, Input, Text } from "native-base";
import { useFocusEffect } from "#react-navigation/native";
import axios from "axios";
import ProductList from "./ProductList";
import SearchedProduct from "./SearchedProducts";
import Banner from "../../Shared/Banner";
import CategoryFilter from "./CategoryFilter";
import baseURL from "../../assets/common/baseUrl";
var { height } = Dimensions.get("window");
const ProductContainer = (props) => {
const [products, setProducts] = useState([]);
const [productsFiltered, setProductsFiltered] = useState([]);
const [focus, setFocus] = useState();
const [categories, setCategories] = useState([]);
const [productsCtg, setProductsCtg] = useState([]);
const [active, setActive] = useState();
const [initialState, setInitialState] = useState([]);
const [loading, setLoading] = useState(true);
useFocusEffect(
useCallback(() => {
setFocus(false);
setActive(-1);
// Products
axios
.get(`${baseURL}products`)
.then((res) => {
setProducts(res.data);
setProductsFiltered(res.data);
setProductsCtg(res.data);
setInitialState(res.data);
setLoading(false);
})
.catch((error) => {
console.log("Api call error");
});
// Categories
axios
.get(`${baseURL}categories`)
.then((res) => {
setCategories(res.data);
})
.catch((error) => {
console.log("Api call error");
});
return () => {
setProducts([]);
setProductsFiltered([]);
setFocus();
setCategories([]);
setActive();
setInitialState();
};
}, [])
);
// Product Methods
const searchProduct = (text) => {
setProductsFiltered(
products.filter((i) => i.name.toLowerCase().includes(text.toLowerCase()))
);
};
const openList = () => {
setFocus(true);
};
const onBlur = () => {
setFocus(false);
};
// Categories
const changeCtg = (ctg) => {
{
ctg === "all"
? [setProductsCtg(initialState), setActive(true)]
: [
setProductsCtg(
products.filter((i) => i.category._id === ctg),
setActive(true)
),
];
}
};
return (
<>
{loading == false ? (
<Container>
<Header searchBar rounded>
<Item>
<Icon name="ios-search" />
<Input
placeholder="Search"
onFocus={openList}
onChangeText={(text) => searchProduct(text)}
/>
{focus == true ? (
<Icon onPress={onBlur} name="ios-close" />
) : null}
</Item>
</Header>
{focus == true ? (
<SearchedProduct
navigation={props.navigation}
productsFiltered={productsFiltered}
/>
) : (
<ScrollView>
<View>
for the banner of the home page
<View>
<Banner />
</View>
<View>
<CategoryFilter
categories={categories}
categoryFilter={changeCtg}
productsCtg={productsCtg}
active={active}
setActive={setActive}
/>
</View>
{productsCtg.length > 0 ? (
<View style={styles.listContainer}>
{productsCtg.map((item) => {
return (
<ProductList
navigation={props.navigation}
key={item.name}
item={item}
/>
);
})}
</View>
) : (
<View style={[styles.center, { height: height / 2 }]}>
<Text>No products found</Text>
</View>
)}
</View>
</ScrollView>
)}
</Container>
) : (
// Loading
<Container style={[styles.center, { backgroundColor: "#f2f2f2" }]}>
<ActivityIndicator size="large" color="red" />
</Container>
)}
</>
);
};
const styles = StyleSheet.create({
container: {
flexWrap: "wrap",
backgroundColor: "gainsboro",
},
listContainer: {
height: height,
flex: 1,
flexDirection: "row",
alignItems: "flex-start",
flexWrap: "wrap",
backgroundColor: "gainsboro",
},
center: {
justifyContent: "center",
alignItems: "center",
},
});
export default ProductContainer;
I solve this error with change my IDE.
When I migrate from VS Code to sublime text or notepad++ or android studio, this error solved.

React Native Flatlist inside Wrapper Component break the scolling

Hello i have a Problem with my wrapper component. If i put inside the Flatlist component the scrolling doesn't work anymore. I try to pur everywhere flex:1 (on flatlist, on the wrapper itself) but no changes still broken.
What is my mistake?
I expected the normal scroll behavior.
import React from 'react';
import { KeyboardAvoidingView, TouchableWithoutFeedback, Keyboard, Platform } from 'react-native';
const KeyboardAvoidingViewWrapper = ({ children, keyboardOffset }) => {
const additionalOffset = Platform.OS === 'ios' ? 0 : 17;
return (
<KeyboardAvoidingView
keyboardVerticalOffset={keyboardOffset ? keyboardOffset + additionalOffset : 65 + additionalOffset}
behavior={Platform.OS == "ios" ? "padding" : "height"}
style={{ flex: 1, }}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
{children}
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
)
}
export default KeyboardAvoidingViewWrapper;
In the Screen:
<KeyboardAvoidingViewWrapper>
<View style={{ flex: 1 }}>
<FlatList
data={data}
.....
/>
</View>
</KeyboardAvoidingViewWrapper>
Any help is more than appreciate. Thank you.
try giving 'position' to behavior property to your KeyboardAvoidingView.
<KeyboardAvoidingView behavior='position'>

React-Native display image or video on mime/file type condition

i am making a gallery app using React-Native with node.js , I got a data from Node.js api, i want to display files either image or video depends on file type in a FlatList , I don't know how to write the condition for that,
{items.file_Name == 'mp4' ? Video : image }
I am trying to use the above code but i don't know how to get the file name. So please check my code
export default class HomeScreen extends React.Component {
constructor(Props) {
super(Props);
this.state = {
error: null,
Posts:[
{"id":166,"user_id":1,"description":"7th test","file_Name":[VID-WA0005.mp4"]},
{"id":10,"user_id":3,"description":" 6th test","file_Name":["10.jpg", "12.jpg"]},
{"id":9,"user_id":2,"description":" 5th test","file_Name":["9.jpg", "14.jpg"]} ],
}
}
render() {
const { Posts } = this.state
return (
<View style={styles.container}>
<View style={styles.tabContent}>
<FlatList style={styles.list}
data={this.state.Posts}
keyExtractor={(data_posts, index) => {
return data_posts.id.toString();
}}
ItemSeparatorComponent={() => {
return (
<View style={styles.separator} />
)
}}
renderItem={(post, id) => {
const items = post.item;
return (
<View style={styles.card}>
<View style={styles.cardHeader}>
<Text style={styles.title}>{items.description}</Text>
</View>
<View style={styles.cardContent}>
{items.file_Name.split('.').reverse()[0] == 'mp4' ?
<Video
source={{ uri: "http://192.168.1.2:3200/" + items.file_Name }}
style={{ width: '100%', height: 600 }}
resizeMode="cover"
paused={this.state.paused}
controls={true}
volume={this.state.volume}
muted={this.state.muted}
paused={this.state.paused}
onLoad={this.onLoad}
onBuffer={this.onBuffer}
onProgress={this.onProgress}
/>
:
<Image style={styles.cardImage} source={{ uri: "http://192.168.1.2:3200/" + item.file_Name }} />
}
</View>
</View>
)
}}
/>
{/* Flatlist Ends*/}
</View>
</View>
);
}
}
````
I tried with condition like
````{items.file_Name.split('.').reverse()[0] == 'mp4' ? <Video /> : <image />}````
But its not working because i am unable to get the file type.
If anyone know how to get the file name and how to display either video or image please tell me .
You can use endsWith() function is used to check whether the given string ends with the characters of the specified string or not
{items.file_Name.toString().endsWith("mp4") ? Video : image }
Try this
{items.file_Name.split('.').pop() == 'mp4'?<Video /> : <image />}

Implemeting drawer in React native application

I just created my first interface in my React native app. I created a navbar in which there is a menu button to click, so the drawer opens and i can navigate from one screen to another. I intend to use this https://github.com/root-two/react-native-drawer.
I know i need to call open drawer in the menu button when click and here is the code i used, that displays an alert for now
openDrawer(){
this.drawer.open()
}
render() {
return (
<Container>
<Navbar
bgColor={'#C0C0C0'}
title={"Det globale flyktningbildet"}
titleColor="white"
left={{
icon: "ios-menu",
iconColor: "#FFFFFF",
// onPress: () => {alert('Toggle menu ')}
onPress: () => {this.props.openDrawer}
}}
/>
<Drawer
type="static"
// content={<ControlPanel />}
openDrawerOffset={100}
styles={{main: {shadowColor: "#000000", shadowOpacity: 0.4, shadowRadius: 3}}}
tweenHandler={Drawer.tweenPresets.parallax}>
</Drawer>
<View>
<Image
source = { require('./../images/image1_2.png')}
style={[styles.image1, {resizeMode: 'contain'}]}
/>
</View>
</Container>
);
}
So can you please help me implemet the drawer and navigate between different screens
Go through example code in github you will get the idea or you can refer https://stackoverflow.com/a/42748086/6423570
EDIT
You should wrap root container of the screen with Drawer component. The <ControlPanel /> component is the content that should be displayed in the drawer. You could use Touchable Components in the <ControlPanel /> and navigator to navigate between screens. And the openDrawer function is not a prop, call it as this.openDrawer
render() {
return (
<Drawer
type="static"
// content={<ControlPanel />}
openDrawerOffset={100}
styles={{
main: {
shadowColor: "#000000",
shadowOpacity: 0.4,
shadowRadius: 3
}
}}
tweenHandler={Drawer.tweenPresets.parallax}
>
<Container>
<Navbar
bgColor={'#C0C0C0'}
title={"Det globale flyktningbildet"}
titleColor="white"
left={{
icon: "ios-menu",
iconColor: "#FFFFFF",
// onPress: () => {alert('Toggle menu ')}
onPress: () => {this.openDrawer}
}}
/>
<View>
<Image
source = { require('./../images/image1_2.png')}
style={[styles.image1, {resizeMode: 'contain'}]}
/>
</View>
</Container>
</Drawer>
);
}

Resources