This was working fine within the Login.js component:
<View style={{flexDirection: 'row', justifyContent:"center"}}>
<TouchableHighlight onPress={() => this.onPressSocialButton('tel')} >
<Image source={require('./img/icono-tel.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
<TouchableHighlight onPress={() => this.onPressSocialButton('wa')}>
<Image source={require('./img/icono-whatsapp.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
<TouchableHighlight onPress={() => this.onPressSocialButton('fb')}>
<Image source={require('./img/icono-like.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
<TouchableHighlight onPress={() => this.onPressSocialButton('ingrm')}>
<Image source={require('./img/icono-like-instagram.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
</View>
onPressSocialButton = (media) => {
if (media === 'tel') {
this.props.navigation.navigate('TelUtiles');
} else if (media === 'wa') {
Linking.openURL('whatsapp://send?text==%C2%A1Hola!%20Quiero%20realizar%20una%20consulta.&phone=5493416931539').catch(err => console.error('An error occurred', err));
} else if (media === 'fb') {
Linking.openURL('https://www.facebook.com/n/?mascotaweb');
} else if (media === 'ingrm') {
Linking.openURL('http://instagram.com/_u/mascotaweb');
}
};
But when i move this to a separated component i receive the error in the title of this post.
SocialFooter.js:
import React, { Component } from 'react';
import {
View,
Image,
TouchableHighlight,
Linking
} from 'react-native';
export default class SocialFooter extends Component {
static navigationOptions = { header: null }
constructor(props) {
super(props);
}
onPressSocialButton = (media) => {
if (media === 'tel') {
this.props.navigation.navigate('TelUtiles');
} else if (media === 'wa') {
Linking.openURL('whatsapp://send?text==%C2%A1Hola!%20Quiero%20realizar%20una%20consulta.&phone=5493416931539').catch(err => console.error('An error occurred', err));
} else if (media === 'fb') {
Linking.openURL('https://www.facebook.com/n/?mascotaweb');
} else if (media === 'ingrm') {
Linking.openURL('http://instagram.com/_u/mascotaweb');
}
};
render() {
return (
<View style={{flexDirection: 'row', justifyContent:"center"}}>
<TouchableHighlight onPress={() => this.onPressSocialButton('tel')} >
<Image source={require('./img/icono-tel.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
<TouchableHighlight onPress={() => this.onPressSocialButton('wa')}>
<Image source={require('./img/icono-whatsapp.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
<TouchableHighlight onPress={() => this.onPressSocialButton('fb')}>
<Image source={require('./img/icono-like.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
<TouchableHighlight onPress={() => this.onPressSocialButton('ingrm')}>
<Image source={require('./img/icono-like-instagram.png')} style={{width:70, height:70,margin:10}} />
</TouchableHighlight>
</View>
)
}
}
I've tried adding const { navigation:navigate } = this.props;within the onPress method, also i tried binding this in the constructor, like: this.onPressSocialButton = this.onPressSocialButton.bind(this);
Nothing worked, please help me. thanks!
Solved by adding:
const { navigation } = this.props; in the parent component's render() method (Login.js)
then i passed it to the child component like this:
<SocialFooter navigation={navigation}/>
Navigation prop is only supplied to the react-navigation screens which you have already configured, if you need to use the navigation prop in any other components, you need to pass it as a prop
<SocialFooter navigation={navigation}/>
Related
Description:
Wanted to implement ErrorBoundary on react native, but cannot update the ErrorBoundary's State by catching error from descendent components (Header for example). If I by deadult set error to not null. The UI renders. But it is not updating when child component is throwing error. Also tried
Code:
class ErrorBoundary extends Component {
constructor(props) {
super(props)
this.state = {
error: null,
errorInfo: null,
}
}
componentDidCatch(error, errorInfo) {
console.log("Error: ", error, errorInfo)
this.setState({
error: error,
errorInfo: errorInfo,
});
console.log("ErrorBoundary: ", this.error, this.errorInfo)
}
render() {
console.log("ErrorBoundary: ", this.state.error, this.state.errorInfo)
if (this.state.errorInfo) {
return (
<View style={styles.container}>
<Text style={styles.text}>Something went wrong</Text>
<TouchableOpacity
style={styles.button}
onPress={() => {
this.setState({ error: null, errorInfo: null });
}}
>
<Text style={styles.buttonText}>Try again</Text>
</TouchableOpacity>
</View>
);
}
return this.props.children;
}
}
// Header.js
const Header = ({ text }) => {
return (
<View style={styles.headerContainer}>
{/* <TouchableOpacity style={styles.instructContainer}>
<View style={styles.instructView}>
<Text style={styles.instructText}>Instructions</Text>
<Feather name="arrow-down" size={20} style={styles.instructIcon} />
</View>
</TouchableOpacity> */}
<View style={{width: '30%'}} ></View>
<Text style={styles.captureText}>{text}</Text>
<TouchableOpacity
style={styles.logoutContainer}
onPress={() => { throw new Error("I crashed!") }}
>
<Text style={{ color: "white", fontSize: 16 }}>Logout</Text>
</TouchableOpacity>
</View>
);
};
// CameraScreen.js
`const CameraScreen = () => {
return (
<View style={styles.container}>
<ErrorBoundary>
<Header text="Capture Image" />
</ErrorBoundary>
</View>
);
};
I made 2 screens home and editing screen. I want to change values from edit screen without redux and context but I don't know how? and also when I click save in editscreen it's throwing error that undefined is not an object (evaluating '_this.props.navigation.goBack') and displaing blank home screencwhy that's happening. Can some one help me please, below is my code
home.js
class Home extends Component {
state = {
modal: false,
editMode: false.
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
image: require("../assets/dog.jpg"),
},
{
key: "2",
title: "John Cena",
des: "As you can see, You can't see me!",
image: require("../assets/cena.jpg"),
},
],
};
addPost = (posts) => {
posts.key = Math.random().toString();
this.setState((prevState) => {
return {
post: [...prevState.post, posts],
modal: false,
};
});
};
onEdit = (data) => {
this.setState({ post: { title: data }, editMode: false });
};
render() {
if (this.state.editMode)
return <EditScreen item={item} onEdit={this.onEdit} />;
return (
<Screen style={styles.screen}>
<Modal visible={this.state.modal} animationType="slide">
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.modalContainer}>
<AddPost addPost={this.addPost} />
</View>
</TouchableWithoutFeedback>
</Modal>
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<TouchableOpacity
activeOpacity={0.7}
onPress={() => this.setState({ editMode: true })}
style={styles.Edit}
>
<MaterialCommunityIcons
name="playlist-edit"
color="green"
size={35}
/>
</TouchableOpacity>
<Card>
<Image style={styles.image} source={item.image} />
<View style={styles.detailContainer}>
<Text style={styles.title} numberOfLines={1}>
{item.title}
</Text>
<Text style={styles.subTitle} numberOfLines={2}>
{item.des}
</Text>
</View>
</Card>
</>
)}
/>
</Screen>
Edit.js
import React, { Component } from "react";
import { View, StyleSheet, Image, KeyboardAvoidingView } from "react-native";
import colors from "../config/colors";
import AppButton from "../components/AppButton";
import AppTextInput from "../components/AppTextInput";
class EditScreen extends Component {
render() {
const { item, onEdit, onClose } = this.props;
return (
<KeyboardAvoidingView
behavior="position"
keyboardVerticalOffset={Platform.OS === "ios" ? 0 : 100}
>
<Image style={styles.image} source={item.image} />
<View style={styles.detailContainer}>
<AppTextInput value={item.title} />
<AppTextInput value={item.des} />
</View>
<AppButton
text="Save"
onPress={() => {
onEdit(this.state);
}}
/>
</KeyboardAvoidingView>
);
}
}
export default EditScreen;
AppTextInput.js
function AppTextInput({ icon, width = "100%", ...otherProps }) {
return (
<View style={[styles.container, { width }]}>
<TextInput
placeholderTextColor={defaultStyles.colors.medium}
style={defaultStyles.text}
{...otherProps}
/>
</View>
);
}
Try this:
Edit.js
import React, { Component } from 'react';
import { View, StyleSheet, Image, KeyboardAvoidingView } from 'react-native';
import colors from '../config/colors';
import AppButton from '../components/AppButton';
import AppTextInput from '../components/AppTextInput';
class EditScreen extends Component {
constructor(props) {
super(props);
this.state = { ...props.item };
}
render() {
const { onEdit, onClose } = this.props;
const { title, des, image } = this.state;
return (
<KeyboardAvoidingView
behavior="position"
keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 100}>
<Image style={styles.image} source={image} />
<View style={styles.detailContainer}>
<AppTextInput
value={title}
onChangeText={text => this.setState({ title: text })}
/>
<AppTextInput
value={des}
onChangeText={text => this.setState({ des: text })}
/>
</View>
<AppButton text="Save" onPress={() => onEdit(this.state)} />
</KeyboardAvoidingView>
);
}
}
export default EditScreen;
onEdit
onEdit = data => {
const newPosts = this.state.post.map(item => {
if(item.key === data.key) return data;
else return item;
})
this.setState({ post: newPosts, editMode: false });
};
Only the direct children of a navigator can access
this.props.navigation
If you want to access that inside the edit screen you can pass it from the Home screen as a prop. Like so:
return <EditScreen item={item} onEdit={this.onEdit} navigation={this.props.navigation} />;
But i don't think you need to go back because you are still on the Home page and just rendering the EditScreen within it. So just changing the state to have editMode: false should be enough
When I want to distribute my data from my firebase database to my React Native mobile application in the form of a carousel with SwiperFlatList, an error is displayed
each time my class is updated, showing me as follows: "Invariant violation: scrolltoindex out of range: requested Nan but maximum is 1."
By hiding the error the carousel works well but it can be very annoying and cause problems during its build.
Here are my codes:
My Render function :
renderPost=post=>{
return(
<View style={styles.card}>
<HorizontalCard title={post.title_new} desc={post.text} img={post.image} />
</View>
)
}
HorizontalCard Component :
export default class HorizontalCard extends Component {
constructor(props) {
super(props);
}
static propTypes = {
screen: PropTypes.string,
title: PropTypes.string,
desc: PropTypes.string,
img: PropTypes.string,
};
state = {
modalVisible: false,
};
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{flex: 1}}>
<TouchableOpacity
onPress={() => {
this.setModalVisible(true);
}}
style={styles.container}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<View style={{marginTop: 22}}>
<View>
<Text>{this.props.desc}</Text>
<Button
title="Fermer la fenĂȘtre"
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}} />
</View>
</View>
</Modal>
<View style={styles.card_discord}>
<Image style={styles.card_discord_img} source={{ uri: this.props.img }} />
<LinearGradient
start={[1.0, 0.5]}
end={[0.0, 0.5]}
colors={['rgba(51, 51, 51, 0.2)', '#333333', '#333333']}
style={styles.FadeAway}>
<View style={styles.FadeAway}>
<Text h4 style={styles.FadeAway_h2}>
{this.props.title}
</Text>
<Text style={styles.FadeAway_p}>{this.props.desc}</Text>
</View>
</LinearGradient>
</View>
</TouchableOpacity>
</View>
);
}
}
My HomeScreen component (page where the error appears) :
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.ref = Fire.shared.firestore.collection('posts')
this.useref=
this.state={
dataSource : [],
}
}
feedPosts = (postSnapShot) =>{
const post = [];
postSnapShot.forEach((doc) => {
const {uid,text,timestamp,title_new,image} = doc.data();
const data=Fire.shared.firestore
.collection('users')
.doc(uid)
.get()
.then(doc=>{
post.push({
text,
timestamp,
title_new,
image,
uid,
})
this.setState({
dataSource : post,
});
})
});
}
renderPost=post=>{
return(
<View style={styles.card}>
<HorizontalCard title={post.title_new} desc={post.text} img={post.image} />
</View>
)
}
render() {
return (
<ThemeProvider>
<ScrollView>
<SwiperFlatList
autoplay
autoplayDelay={5}
index={0}
autoplayLoop
autoplayInvertDirection
data={this.state.dataSource}
renderItem={({item})=>this.renderPost(item)}
/>
...
<ScrollView>
</ThemeProvider>
)
}
}
I have a dummy Login code with formik form in react-native
import React, { Component } from "react";
import {
TextInput,
Text,
Alert,
Image,
View,
TouchableOpacity,
SafeAreaView,
ScrollView
} from "react-native";
import styles from "./Styles/LoginStylesheet";
import { KeyboardAccessoryNavigation } from "react-native-keyboard-accessory";
import { Formik } from "formik";
import schemaObject, { initialValues, refs } from "./Validations/LoginValidations";
export default class LoginView extends Component {
constructor(props) {
super(props);
this.state = {
activeInputIndex: 0
};
}
handleFocus = index => () => {
this.setState({
activeInputIndex: index
});
};
handleFocusNext = () => {
if (this.state.activeInputIndex + 1 >= refs.length) {
return;
}
refs[this.state.activeInputIndex + 1].focus();
};
handleFocusPrevious = () => {
if (this.state.activeInputIndex - 1 < 0) {
return;
}
refs[this.state.activeInputIndex - 1].focus();
};
handleLogin = () => {
console.log("ACTIOn");
// this.formik.handleSubmit();
};
render() {
return (
<View style={styles.safeAreaView}>
<SafeAreaView style={styles.safeAreaView}>
<ScrollView style={styles.superView}>
<Formik {/* LINE 56 */}
initialValues={initialValues}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={schemaObject}
ref={p => (this.formik = p)}
>
{({
values,
handleChange,
errors,
setFieldTouched,
touched,
isValid,
handleSubmit
}) => (
<View style={styles.superView}>
<View style={styles.logoParentView}>
<Image
source={require("../../Resources/Assets/Login/aptihealth_logo.png")}
resizeMode={"contain"}
style={styles.logo}
/>
</View>
<View style={styles.emailParentView}>
<Text style={styles.titleLabel}>Email Id</Text>
<TextInput
value={values.emailId}
onChangeText={handleChange("emailId")}
onBlur={() => setFieldTouched("emailId")}
placeholder="Email Id"
style={styles.textInput}
autoCorrect={false}
onFocus={this.handleFocus(0)}
ref={input => {
refs[0] = input;
}}
/>
{touched.emailId && errors.emailId && (
<Text style={{ fontSize: 10, color: "red" }}>
{errors.emailId}
</Text>
)}
</View>
<View style={styles.passwordParentView}>
<Text style={styles.titleLabel}>Password</Text>
<TextInput
value={values.password}
onChangeText={handleChange("password")}
placeholder="Password"
onBlur={() => setFieldTouched("password")}
style={styles.textInput}
autoCorrect={false}
secureTextEntry={true}
onFocus={this.handleFocus(1)}
ref={input => {
refs[1] = input;
}}
/>
{touched.password && errors.password && (
<Text style={{ fontSize: 10, color: "red" }}>
{errors.password}
</Text>
)}
</View>
<View style={styles.forgotPasswordParentView}>
<TouchableOpacity
style={styles.forgotpasswordButton}
activeOpacity={0.7}
>
<Text>Forgot Password?</Text>
</TouchableOpacity>
</View>
<View style={styles.loginParentView}>
<TouchableOpacity
onPress={() => {
console.log("VALUES: ", values, this.formik);
this.handleLogin();
}}
style={styles.loginButton}
activeOpacity={0.7}
>
<Text style={styles.loginText}>Login</Text>
</TouchableOpacity>
</View>
<View style={styles.seperaterParentView}>
<View style={styles.seperaterView} />
<Text style={styles.seperaterText}>OR</Text>
<View style={styles.seperaterView} />
</View>
<View style={styles.faceIdLoginParentView}>
<Image
source={require("../../Resources/Assets/face_id_small_color/face_id_small_color.png")}
resizeMode={"contain"}
/>
<TouchableOpacity style={styles.faceIdButton}>
<Text>Sign In with Face ID</Text>
</TouchableOpacity>
</View>
<View style={styles.signUpParentView}>
<TouchableOpacity style={styles.signupButton}>
<Text>Sign Up for Account Here</Text>
</TouchableOpacity>
</View>
</View>
)}
</Formik>
</ScrollView>
</SafeAreaView>
<KeyboardAccessoryNavigation
nextDisabled={false}
previousDisabled={false}
nextHidden={false}
previousHidden={false}
onNext={this.handleFocusNext}
onPrevious={this.handleFocusPrevious}
avoidKeyboard
/>
</View>
);
}
}
I am trying to console formik ref in login action getting undefined value with debug error
ExceptionsManager.js:126 Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Check the render method of `LoginView`.
in Formik (at LoginView.js:56)
I have no idea why it's getting undefined ??
You should take a look at this issue.
You problem is here
<Formik
initialValues={initialValues}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={schemaObject}
ref={p => (this.formik = p)} {/* passing this ref will throw the error */}
>
In the latest version of Formik, they changed Formik to a functional component as explained in the issue, which gives you this error if you pass ref's.
You can check for the suggestions on the issue or wait until they release an update with the correction.
Edit:
Formik made an update and now you can use ref with the prop innerRef.
Please see this comment
You should change it to
<Formik
initialValues={initialValues}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={schemaObject}
{/* using innerRef instead of ref*/}
innerRef={p => (this.formik = p)} {/* this will give you the formik bag */}
>
And this way you can call this.formik.handleSubmit(), just lik you want to do.
The goal is to pass the State of the Photos from my CameraRoll.js (Modal) to EventCreator.js(Modal) without using the React Redux. I'm using React Native Navigation V1.
I'm wondering maybe it is possible state of photos: [] become props? Just don't know how to do it. Need help, thank you guys!
Here are my codes:
CameraRoll.js:
state = {
photos: [],
index: null,
pickedImage: null
}
getPhotos = () => {
CameraRoll.getPhotos({
first: 200,
assetType: 'All'
})
.then(res => {
this.setState({
photos: res.edges,
});
})
.catch((err) => {
console.log('Error image: ' + err);
});
};
render() {
return(
<View style={styles.container}>
<Image source={{uri: this.state.pickedImage}} style={styles.image}/>
<ScrollView contentContainerStyle={styles.scrollView} showsVerticalScrollIndicator={false}>
{this.state.photos.map((photos, index) => {
return(
<TouchableHighlight
style={{opacity: index === this.state.index ? .5 : 1}}
onPress={() => this.setState({pickedImage: photos.node.image.uri})}
key={index}
underlayColor='transparent'
>
<Image
style={{width: width / 3, height: width /3}}
source={{uri: photos.node.image.uri}}
resizeMode='cover'
/>
</TouchableHighlight>
);
})}
</ScrollView>
</View>
);
}
EventCreator.js:
render(){
return(
<View style={styles.container}>
<EventInput
titleOnChangeText={this.eventNameChangedHandler}
descriptionOnChangeText={this.eventDescriptionChangedHandler}
titleEvent={this.state.controls.eventName}
descriptionEvent={this.state.controls.eventDescription}
/>
<Image
style={styles.image}
source={"I want to pass the image here from CameraRoll.js"}
resizeMode='contain'
/>
</View>
);
}
if you mean this:
onPress={() => this.setState({pickedImage: photos.node.image.uri})}
it just change the state value. What you should do is put an if statement on the return of cameraRoll.js:
private onPress = (img) => {
this.props.onImagePicked(img)
}
render() {
return(
<View style={styles.container}>
<Image source={{uri: this.state.pickedImage}} style={styles.image}/>
<ScrollView contentContainerStyle={styles.scrollView} showsVerticalScrollIndicator={false}>
{this.state.photos.map((photos, index) => {
return(
<TouchableHighlight
style={{opacity: index === this.state.index ? .5 : 1}}
onPress={() => this.onPress(photos.node.image.uri))}
key={index}
underlayColor='transparent'
>
<Image
style={{width: width / 3, height: width /3}}
source={{uri: photos.node.image.uri}}
resizeMode='cover'
/>
</TouchableHighlight>
);
})}
</ScrollView>
</View>
);
}
And in EventCreator.js:
constructor(){
super(props);
this.state = {
pickedImg: undefined
}
}
private onImagePicked = (newImg) => {
this.setState({
pickedImg: newImg
})
}
render(){
return(
<View style={styles.container}>
<EventInput
titleOnChangeText={this.eventNameChangedHandler}
descriptionOnChangeText={this.eventDescriptionChangedHandler}
titleEvent={this.state.controls.eventName}
descriptionEvent={this.state.controls.eventDescription}
/>
<Image
style={styles.image}
source={this.props.source}
resizeMode='contain'
/>
<CameraRoll props={...} onImagePicked={this.onImagePicked}/>
</View>
);
}