Invalide hook call, Hooks can only be calle inside of the body of a function component - react-native

i created a functionnal component
import React from 'react';
import { View, ScrollView, Text, SafeAreaView } from 'react-native';
import { useState, useEffect } from 'react';
const listFiliere = ({item}) => {
const [show, setShow] = useState(false);
return(
<View style={{ height: 30, flex: 1, justifyContent: 'center', borderBottomWidth: 1, borderBottomColor: 'blue' }}>
<Text>{ item.name }</Text>
</View>
);
}
export default listFiliere
I called this one inside class component for renderItem of flatlist; and it return error of invlide hook call; Is the class component which called it the cause or anything else?

it could be a few things. the code you posted is not a lot to go on. Take a look at this page. A few things you can check

If the problem is that you are calling useState in a class component, please reference this post.
Basically, you cannot use the useState hook in a class component. The class component equivalent would be:
export class ListFiliere extends React.Component {
constructor(props) {
super(props);
this.state = {
show: false
};
}
render() {
return(
<View style={{ height: 30, flex: 1, justifyContent: 'center', borderBottomWidth: 1, borderBottomColor: 'blue' }}>
<Text>{ item.name }</Text>
</View>
);
}
}

Related

I need to fix bug with react native. what is the problem?

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
import React, { PureComponent, useState } from 'react'
import { StoryContainer } from 'react-native-stories-view'
import {
TouchableOpacity,
Alert,
StyleSheet,
View,
Text,
SafeAreaView,
ImageBackground,
Image,
Platform,
StatusBar,
} from 'react-native'
import { connect } from 'react-redux'
class StoryViewScreen extends PureComponent {
constructor(props) {
super(props);
this.state = {
}
}
render() {
const { files } = this.props.route.params;
const fileUrls = [];
for (var i = 0; i < files.length; i++) {
fileUrls.push(files[i].uri);
}
console.log("files path:", fileUrls);
return (
<View style={{ flex: 1, flexDirection: 'column' }}>
{Platform.OS === 'ios' && (
<View style={{
backgroundColor: 'gray',
height: 45,
}}>
<StatusBar barStyle="light-content" backgroundColor={'green'} />
</View>
)}
{Platform.OS === 'android' && (
<StatusBar barStyle="dark-content" backgroundColor={'white'} />
)}
<SafeAreaView style={{ flex: 1, flexDirection: 'column', backgroundColor: 'gray' }}>
<StoryContainer
visible={true}
enableProgress={false}
images={fileUrls}
duration={5}
containerStyle={{
width: '100%',
height: '100%',
}} />
{/* <Text>This is teh realdksfjdsklfj</Text> */}
</SafeAreaView>
</View>
);
}
};
const style = StyleSheet.create({
});
function mapStateToProps(state) {
return {
// currentUser: state.user.currentUser,
};
}
function mapDispatchToProps(dispatch) {
return {
dispatch
};
}
export default connect(mapStateToProps, mapDispatchToProps)(StoryViewScreen);
You cannot use useState in class component, instead use setState to set the state.

How to write Custom flash message in react native

I want to display a custom message after successful record update when boolean value of recordUpdateSuccess become true and after 3seconds it should disappear.
{recordUpdateSuccess ? this.renderRecordUpdatedSucess() : null}
I have function to display message:
renderRecordUpdatedSucess = () => (
<View style={styles.sucessAlert}>
<Text style={styles.sucessAlert}>Record updated successfully.</Text>
</View>
)
I tried to use setTimeout() to display message but not working.
Any idea to acheive this one.
I don't want to use Toast, any third party library for this one.
Custom flash message (No external Library)
Working Example: https://snack.expo.io/#msbot01/1dcddc
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
flashMessage: false
}
}
onPress(){
this.setState({
flashMessage: true
},()=>{setTimeout(() => this.closeFlashMessage(), 3000)})
}
closeFlashMessage(){
this.setState({
flashMessage: false
})
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=>{this.onPress()}}>
<Text>Click Me</Text>
</TouchableOpacity >
{this.state.flashMessage==true?
<View style={styles.flashMessage}>
<Text style={{color:'white'}}>This is custom Flash message</Text>
</View>
:
null
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
flashMessage:{
position:'absolute',
backgroundColor:'green',
width:'100%',
justifyContent:'center',
alignItems:'center',
height:40,
top:0
}
});

React-Native Constructor

Please help me find what is wrong in the following React-Native code?
It says after constructor (props) should have ';' semicolon. I don't know if I declared it in the right way.
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default function App() {
constructor (props){
this.state = {
text: 'HI'
}
}
render () {
return (
<View style={styles.container}>
<TextInput style={styles.input}
placeholder = 'Enter Value...'
placeholderTextColor ='#E74292'
onChangeText = {(text) => {
this.setState({text})
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor:'#F4C724',
},
input :{
marginTop:30,
height:30,
width:30,
borderWidth:2,
padding:10,
borderRadius: 5,
borderColor:'#1287A5'
}
}
);
You should declare the component as class instead of function if you want a constructor:
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default class App {
constructor(props) {
this.state = {
text: 'HI'
};
}
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Enter Value..."
placeholderTextColor="#E74292"
onChangeText={text => {
this.setState({ text });
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F4C724'
},
input: {
marginTop: 30,
height: 30,
width: 30,
borderWidth: 2,
padding: 10,
borderRadius: 5,
borderColor: '#1287A5'
}
});
constructor only works in class based component so switch to class based component rather than . functional whihc is now.
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default class App extends React.Component{
constructor(props) {
this.state = {
text: 'HI'
};
}
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Enter Value..."
placeholderTextColor="#E74292"
onChangeText={text => {
this.setState({ text });
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F4C724'
},
input: {
marginTop: 30,
height: 30,
width: 30,
borderWidth: 2,
padding: 10,
borderRadius: 5,
borderColor: '#1287A5'
}
});
You need to study the difference between functional and class component.
Functional component is just a plain java-script function which also known as stateless component. They do not manage their own state or have access to the lifecycle methods.
for more please follow the link below:
https://medium.com/#Zwenza/functional-vs-class-components-in-react-231e3fbd7108
you can use useState , the dynamic function value loads to the initial variable on load
import React,{ useState } from 'react';
import { View, Text, Button, ImageBackground} from 'react-native';
export default function Home({navigation}){
//function getversion onload
const [initval,setInitval] = useState(()=>{ return '123456'});
return(
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text> {initval} </Text>
</View>
);
}
You cannot have a constructor() in functional components. You should either change function component to class component or go and check out the react doc about React Hooks. You are going to have a better understanding of the differences between react class components and react functional components.

How to set default props values to custom state less component in React Native

I have a really simple component, called Divider here is the source code:
import React from "react";
import { StyleSheet, View } from "react-native";
export default class Divider extends React.Component {
render() {
return (
<View style = { styles.separator } />
);
}
}
const styles = StyleSheet.create({
separator: {
height: StyleSheet.hairlineWidth,
marginBottom: 8,
backgroundColor: "#FFFFFF80",
},
});
What I am trying to achieve is that the values in styles.separator becomes the default values of this component, since those are the values which I am using in most cases, but in some edge cases I need to change the marginBottom to 16 for example.
So most case I just want to do <Divider />, but sometimes <Divider marginBottom = 16 />
What I have currently is something like this below, but obviously this doesn't work.
import React from "react";
import { StyleSheet, View } from "react-native";
export default class Divider extends React.Component {
static defaultPropts = {
marginTop: 0,
marginBottom: 8,
backgroundColor: "#FFFFFF80",
}
render() {
return (
<View style = {{
height: StyleSheet.hairlineWidth,
marginTop: {this.props.marginTop},
marginBottom: {this.props.marginBottom},
backgroundColor: {this.props.backgroundColor},
}} />
);
}
}
You can receive your custom style by props and use them in your component style as array. When you call the props style after the component's, it will overwrite any equal style property it already has.
For example, let's say you have a component named 'Card', you can write your component like this:
<View style={[style.cardStyle, props.style]}>
{props.children}
</View>
And call it like this <Card style={{ backgroundColor: '#FFFFFF'}} />
So it's getting all defined 'cardStyle' from it's own component, also adding the styles received by props.
Hope it helps.
EDIT:
You can try something like this
import React from "react";
import { StyleSheet, View } from "react-native";
const Divider = (props) => {
<View style = {{
height: StyleSheet.hairlineWidth,
marginTop: {this.props.marginTop},
marginBottom: {this.props.marginBottom},
backgroundColor: {this.props.backgroundColor},
}} />
}
Divider.defaultProps = {
marginTop: 0,
marginBottom: 8,
backgroundColor: "#FFFFFF80",
}
export default Divider;
Let me know if it works for you.
you can do like this
export default class Divider extends React.Component {
render() {
return (
<View style = {{
height: StyleSheet.hairlineWidth,
marginTop: {this.props.marginTop},
marginBottom: {this.props.marginBottom},
backgroundColor: {this.props.backgroundColor},
}} />
);
}
}
Divider.defaultProps = {
marginTop: 0,
marginBottom: 8,
backgroundColor: "#FFFFFF80",
}
So after researching a bit I found out that this works.
import React from "react";
import { Dimensions, StyleSheet, View } from "react-native";
export default class Divider extends React.Component {
static defaultProps = {
customWidth: Dimensions.get("window").width / 2.0,
}
render() {
const halfWidth = this.props.customWidth
return (
<View style = { [styles.separator, {width: halfWidth}] } />
);
}
}
const styles = StyleSheet.create({
separator: {
height: StyleSheet.hairlineWidth,
backgroundColor: "#FFFFFF80",
},
});
So now whenever I use <Divider /> its width gonna be half of the screen size, but if I dod <Divider customWidth = { 10 }, then it will overwrite the default value and will be 10 dp instead.

Navigated React Native component is not rendered properly after updating its parent's state

I have a parent component with Navigator and 2 child components.
In parent component I have a method that updates the height of a View it has, which I pass to child components, allowing them to refresh the state of the parent once they are mounted.
When I navigate directly to second child, then call this method in second child's componentDidMount, the second child is re-rendered properly.
However, when I navigate from first child to second, the second child is not re-rendered as expected.
Parent:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
Navigator,
View
} from 'react-native';
import FirstChild from './FirstChild';
import SecondChild from './SecondChild';
export default class Parent extends Component {
constructor(props) {
super(props);
this.setViewHeight = this.setViewHeight.bind(this);
this.state = {
viewHeight : 200
}
}
renderScene(route, navigator) {
var child = route.name == 'FirstChild' ?
<FirstChild navigator={navigator} heightSetter={this.setViewHeight}/> :
<SecondChild navigator={navigator} heightSetter={this.setViewHeight}/>;
return (
<View style={styles.container}>
<View style={[styles.dynamicView, {height: this.state.viewHeight}]}/>
{child}
</View>
)
}
render() {
return (
<Navigator
ref='navigator'
initialRoute={{ name: 'FirstChild' }}
renderScene={(route,navigator)=>this.renderScene(route,navigator)}
/>
);
}
setViewHeight() {
this.setState({
viewHeight: 100
})
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignSelf: 'stretch',
justifyContent: 'flex-start',
alignItems: 'center',
},
dynamicView: {
alignSelf: 'stretch',
backgroundColor: 'rgba(100,100,200, 0.5)'
}
});
First Child:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
export default class FirstChild extends Component {
constructor(props) {
super(props)
}
render() {
return (
<TouchableOpacity style={styles.child} onPress={() => this.props.navigator.push({name: 'SecondChild'}) }>
<View style={styles.child}>
<Text>FIRST</Text>
</View>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
child: {
height: 200,
alignSelf: 'stretch',
backgroundColor: 'rgba(200,100,100,0.5)'
}
});
Second Child:
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View
} from 'react-native';
export default class SecondChild extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
this.props.heightSetter();
}
render() {
return (
<View style={styles.child}>
<Text>Second</Text>
</View>
);
}
}
const styles = StyleSheet.create({
child: {
height: 200,
alignSelf: 'stretch',
backgroundColor: 'rgba(200,100,100,0.5)'
}
});
The question you are putting is not clear actually. What is the behavior that you got? Without clear picture of that it's not possible to answer your question but can tell you one thing that is
Using the navigation which is built in to react native is little complex and when there are many scenes to go through it doesn't support at all.
You can use navigation library like react-native router flux, which will definitely help you solve the issue you have got.
Here is the link,
https://github.com/aksonov/react-native-router-flux