react native null is not an object modal - react-native

Why I get this error ?
TypeError: null is not an object (evaluating 'modalSuccess.open')
code:
import React, { useEffect, useState, useRef } from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Image, ImageBackground } from 'react-native';
import { useNavigation } from '#react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import Toast from 'react-native-toast-message';
import { updateVerified, toastShown } from '../redux/slice/authSlice';
import { useDispatch, useSelector } from 'react-redux';
import { Portal } from 'react-native-portalize';
import { ModalCollectionSuccess } from '../components/modal/successCollection/ModalCollectionSuccess';
const Profile = () => {
const navigation = useNavigation();
const dispatch = useDispatch();
const user = useSelector(state => state.user);
let modalSuccess = useRef(null).current;
const handleNavigateToAuthRegister = isUser => {
navigation.navigate('AuthRegister', {
isUser
});
};
const handleSetToastToFalse = () => {
Toast.hide();
dispatch(toastShown({user}))
};
useEffect(() => {
user.showCollectionSuccess === true && modalSuccess.open();
}, [user.showCollectionSuccess]);
return (
<View style={{flex: 1}}>
<StatusBar color="#fff" />
<Toast style={{position: 'absolute', zIndex: 2}} ref={(ref) => Toast.setRef(ref)} />
<Portal>
<ModalCollectionSuccess ref={el => (modalSuccess = el)} />
</Portal>
</View>
)
};
export default Profile;
....................................................................................................................................................................................................

Related

How to resolve "null is not an object" issue with Reducer on React-Native?

I'm working on a React-Native project using expo and I'm facing an issue.
Here is my code.
This is the navSlicer
navSlice.js
import { createSlice } from "#reduxjs/toolkit";
const initialState = {
origin: null,
destination: null,
travelTimeInformation: null,
}
export const navSlice = createSlice ({
name: 'nav',
initialState,
reducers: {
setOrigin: (state, action) => {
state.origin = action.payload;
},
setDestination: (state, action) => {
state.destination = action.payload;
},
setTravelTimeInformation: (state, action) => {
state.travelTimeInformation= action.payload;
},
},
});
export const { setOrigin, setDestination, setTravelTimeInformation} = navSlice.actions;
//Selectors
export const selectOrigin = (state) => state.nav.origin;
export const selectDestination = (state) => state.nav.destination;
export const selectTravelTimeInformation = (state) => state.nav.travelTimeInformation;
export default navSlice.reducer;
HomeScreen.js
import { StyleSheet, Text, View, TextInput, KeyboardAvoidingView, Alert, DeviceEventEmitter } from 'react-native'
import React, { useEffect, useRef, useState } from 'react'
import Map from "../../components/Map"
import CustomInput from './CustomInput'
import CustomButton from './CustomButton'
const HomeScreen = () => {
const [showStart, setShowStart] = useState(false);
const showOrigin = () => {
if(showStart) {
return (
<View>
<CustomInput text="Pornire:" placeholder="Initial location"></CustomInput>
</View>
)
}
}
return (
<View style={styles.container}>
{/* <View style={styles.navbar}>
<Ionicons name='md-arrow-back-outline' onPress={handleBackButton} style={styles.arrow} size={32} ></Ionicons>
<Ionicons name='notifications-outline' style={styles.icons} size={32} ></Ionicons>
<Ionicons name='settings-outline' size={32} ></Ionicons>
</View> */}
<View style={{padding: 15, flex: 0}}>
{showOrigin()}
<CustomInput text="Destinatie" placeholder="Destination"></CustomInput>
<CustomButton text="Cauta" onPress={() => setShowStart(true)}></CustomButton>
</View>
<Map styles={styles.map} />
</View>
)
}
This is my Custom Input file for Homescreen that also contains my GooglePlacesAutocomplete component which comunicates with reducer
CustomInput.js
import { StyleSheet, Text, View, TextInput } from 'react-native'
import React, { useState } from 'react'
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import { GOOGLE_API_KEY } from '#env'
import { useDispatch } from 'react-redux';
import { setDestination, setOrigin } from '../../components/navSlice';
const CustomInput = ({text, placeholder}) => {
const dispatch = useDispatch();
return (
<View>
<Text style={styles.text}>{text}</Text>
<GooglePlacesAutocomplete
styles={{textInput: styles.inputGoogle, container: {flex: 0}}}
placeholder={placeholder}
fetchDetails={true}
enablePoweredByContainer={false}
minLength={2}
onPress={(data, details = null) => {
console.log(data)
console.log(details)
dispatch(setOrigin({
location: details.geometry.location,
description: data.description,
}));
dispatch(setDestination(null));
}}
query={{
key: GOOGLE_API_KEY,
language: 'en',
}}
nearbyPlacesAPI="GooglePlacesSearch"
debounce={400}
/>
</View>
)
}
export default CustomInput
The problem looks like it is coming from Map.js where is my MapView created
import { Dimensions, StyleSheet, Text, View } from 'react-native'
import React from 'react'
import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps'
import { useSelector } from 'react-redux'
import { selectOrigin } from './navSlice'
const Map = () => {
const origin = useSelector(selectOrigin);
return (
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: origin.location.lat,
longitude: origin.location.lng,
latitudeDelta: 0.005,
longitudeDelta: 0.005,
}}
/>
)
}
The error is the following:
ERROR TypeError: null is not an object (evaluating 'origin.location')
This error is located at:
in Map (created by HomeScreen)
in RCTView (created by View)
in View (created by HomeScreen)
in HomeScreen (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)

expo camera issue once it work second time without refresh it can not work

I'm using an expo camera for QRcode scan with react-navigation. it works fine only at first after that use of second time the screen of the camera became black. It can not work. but with refresh the app it work fine once
can any suggest me the best solution for it?
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { Camera } from 'expo-camera';
import {SetHeight,SetWidth}from '../utillies/Display'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import Entypo from 'react-native-vector-icons/Entypo'
import { withNavigationFocus } from 'react-navigation'
const QrcodeReader = ({navigation,isFocused}) => {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return(
<View style={styles.container}>
{isFocused&& <Camera
type={type}
onBarCodeScanned={(...args) => {
const data = args[0].data;
const result = JSON.stringify(data);
navigation.navigate('ItemCollector',{FKUserId:result});
}}
barCodeScannerSettings={{
barCodeTypes: ['qr'],
}}
style={{ flex: 1 }}
>
</Camera>}
</View>
);
}
export default withNavigationFocus(QrcodeReader);

Automatically uncheck checkbox when checking another react native

I have two checkboxes (from react-native elements), let's call them box a and box b, where it should only be possible to have one of them checked at a time (no multiple selection), iow - if box a is checked, it is not possible to check box b. So as of this moment, if I were to have checked box a by mistake, I need to uncheck box a manually by clicking it again, in order to check box b. However, I want to be able to automatically uncheck box a by clicking and checking box b - if that makes any sense.
I have tried to look at both issue 54111540 and others, but none of the answers there seem to help with what I want to achieve.
My code:
import React, { useState } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, } from 'react-native';
import { CheckBox } from 'react-native-elements';
import { Ionicons } from '#expo/vector-icons';
import { slider } from '../../components/SliderStyle';
import { useDispatch } from 'react-redux';
import { addfirstrole } from '../../redux/actions/index';
import store from '../../redux/store';
import * as firebase from 'firebase';
const RoleScreen = ({ navigation }) => {
const dispatch = useDispatch()
const addFirstRole = firstRole => dispatch(addfirstrole(firstRole))
const [landlordChecked, setLandlordChecked ] = useState(false)
const [tenantChecked, setTenantChecked] = useState(false)
const user = firebase.auth().currentUser
return (
<View>
<Text>Role screen</Text>
<CheckBox
title='Jeg er utleier'
checkedIcon='dot-circle-o'
uncheckedIcon='circle-o'
checked={landlordChecked}
onPress={tenantChecked ? () => setLandlordChecked(false) : () => setLandlordChecked(!landlordChecked)}
/>
<CheckBox
title='Jeg er leietaker'
checkedIcon='dot-circle-o'
uncheckedIcon='circle-o'
checked={tenantChecked}
onPress={landlordChecked ? () => setTenantChecked(false) : () => setTenantChecked(!tenantChecked)}
/>
<TouchableOpacity onPress={() => { navigation.navigate('Search'); addFirstRole(user.uid); console.log(store.getState()); }}>
<View style={slider.buttonStyle}>
<Text style={slider.textStyle}>Neste</Text>
<Ionicons name='ios-arrow-forward'style={slider.iconStyle} />
</View>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({})
export default RoleScreen;
Try this, this will help you
import React, { useState } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, } from 'react-native';
import { CheckBox } from 'react-native-elements';
import { Ionicons } from '#expo/vector-icons';
import { useDispatch } from 'react-redux';
import * as firebase from 'firebase';
const RoleScreen = ({ navigation }) => {
const [landlordChecked, setLandlordChecked ] = useState(false)
const [tenantChecked, setTenantChecked] = useState(false)
return (
<View>
<Text>Role screen</Text>
<CheckBox
title='Jeg er utleier'
checkedIcon='dot-circle-o'
uncheckedIcon='circle-o'
checked={landlordChecked}
onPress={landlordChecked ? () => setLandlordChecked(false) : () => [setLandlordChecked(true),setTenantChecked(false)]}
/>
<CheckBox
title='Jeg er leietaker'
checkedIcon='dot-circle-o'
uncheckedIcon='circle-o'
checked={tenantChecked}
onPress={tenantChecked ? () => setTenantChecked(false): () => [setTenantChecked(true),setLandlordChecked(false)]}
/>
</View>
)
}
const styles = StyleSheet.create({})
export default RoleScreen;
Change this according to your requirement. Feel free for doubts
this is How to uncheck other values if one is checked
this is a function we call with onPress
data3.checked is true or falses
data3.filterx.id is filter id
onPress statement is
{data4.map((item) => {
return (
<TouchableOpacity
style={{
flexDirection: "row",
alignItems: "center",
}}
key={item.filterx.id}
onPress={() => handleChange4(item.filterx.id)}
>
<CheckBox checked={item.checked} />
<Text>{item.filterx.title}</Text>
</TouchableOpacity>
);
})}
const handleChange3 = (id) => {
let temp = data3.map((data3) => {
if (id === data3.filterx.id) {
return { ...data3, checked: !data3.checked };
}
return data3;
});
for (var i = 0; i < data3.length; i++) {
data3[i].checked = false;
}
data3.checked = true;
console.log(temp);
setdata3(temp);
};

FlatList Render issue in react-navigation

I am trying to render a FlatList in the home screen using react-navigation after refresing this error message appears:
invariant violation: Objects are not valid as a React child (found: object with keys {screenProps, navigation}). If you meant to render a collection of children, use an array instead.
//App.js
import React from 'react';
import Navigator from './src/Routes/appRoutes';
import { View, Text, StyleSheet } from 'react-native';
import TodoApp from './src/todoApp';
import SingleTodo from './src/components/singleTodo';
const App = () => {
return (
<Navigator />
);
}
const styles = StyleSheet.create(
{
container: {
padding: 40
}
}
)
export default App;
//FlatList screen
import React, { useState } from 'react';
import { View, FlatList } from 'react-native';
import Todos from './components/todos';
import uuid from 'uuid';
const TodoApp = () => {
const [todo, setTodo] = useState([
{
id: uuid(),
title: "FFFFFFFFF",
desc: "first description"
},
{
id: uuid(),
title: "Second title",
desc: "Second description"
}
]
)
return (
<View>
<FlatList
data={todo}
renderItem={({ item }) =>
<Todos title={item.title} desc={item.desc} />}
keyExtractor={item => item.id}
/>
</View>
);
}
export default TodoApp;
//Routes
import { createStackNavigator } from 'react-navigation-stack';
import Todos from './../components/todos';
import SingleTodo from './../components/singleTodo';
import { createAppContainer } from 'react-navigation';
import { Settings } from './../settings';
const screens = {
Home: {
screen: Todos
},
SingleTodo: {
screen: SingleTodo
}
}
const StackScreens = createStackNavigator(screens);
export default createAppContainer(StackScreens);
//Todos screen
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { NavigationNativeContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const Todos = (props) => {
console.log(props);
const { title, desc } = props;
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => props.navigation.navigate('SingleTodoScreen')}>
<View>{props}</View>
<Text style={styles.listText}>{title}</Text>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
container: {
padding: 15,
color: "#000",
borderWidth: 1,
borderColor: "#eee",
},
listText: {
fontSize: 16
}
});
export default Todos;
You need to remove the following line from the code
<View>{props}</View>
props is an object, and you can not write the include the object in your JSX.
So your functional component will be like this.
const Todos = (props) => {
console.log(props);
const { title, desc } = props;
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => props.navigation.navigate('SingleTodoScreen')}>
<Text style={styles.listText}>{title}</Text>
</TouchableOpacity>
</View>
)
}

react-native redux dispatch action from nested components

I am wondering how I can dispatch an action from n-th level nested components. This is wha I have got:
BodyContainer (contains connect, mapProps, mapDispatch, etc.) => Body
=Body (Component) where the actions are dispatched)
==Grid (Component)- state is passed as props from Body and some elements parts of the state are further passed on to the next component as props.
===Square (Component) - receives some part of the state as props.
Now, I'd like to dispatch an action from the Square component to change the state. I thought I'll just do a SquareContainer first but then how would it get the parts of the state from Grid?
See below the components (let me know if you need more information):
BodyContainer:
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { listNumbers, pickNumber } from '../actions/numberActions';
import { populateRow, populateGrid } from '../actions/gridActions';
import Body from '../components/Body';
const mapStateToProps = state => ({
numbers: state.numbers,
grid: state.grid
});
const mapDispatchToProps = dispatch => (
bindActionCreators({
listNumbers,
pickNumber,
populateRow,
populateGrid
}, dispatch)
);
export default connect(
mapStateToProps,
mapDispatchToProps
)(Body);
Body Component
import React, { Component, PropTypes } from 'react';
import { View, StyleSheet, Button } from 'react-native';
import Grid from './Grid';
import * as globalStyles from '../styles/global';
export default class Body extends Component {
componentWillMount() {
this.refresh();
}
refresh() {
this.props.populateGrid();
}
render() {
return (
<View style={styles.body}>
<Grid inGrid={this.props.grid} />
<View style={styles.buttonContainer}>
<Button
onPress={this.refresh.bind(this)}
title={'Regenerate the Grid'}
/>
</View>
</View>
);
}
}
Grid component
import React, { Component, PropTypes } from 'react';
import { View, StyleSheet } from 'react-native';
import Square from './Square';
import * as globalStyles from '../styles/global';
export default class Grid extends Component {
render() {
const row = [];
let i = 0;
this.props.inGrid.forEach((r) => {
r.forEach((c) => {
i++;
row.push(
<Square key={i} sqValue={c} />
);
});
});
const { grid } = styles;
return (
<View style={grid}>
{row}
</View>
);
}
}
Square Component
import React, { PropTypes } from 'react';
import { View, Text, StyleSheet, TouchableHighlight } from 'react-native';
import * as globalStyles from '../styles/global';
const Square = ({ sqValue }) => {
const { square, textStyle, squareActive } = styles;
return (
<TouchableHighlight
style={[square, sqValue[1] && squareActive]}
onPress={() => console.log(sqValue[0])}
>
<View>
<Text style={textStyle}>{sqValue[0]},{sqValue[1]}</Text>
</View>
</TouchableHighlight>
);
};
Edit: I've changed the Square component to a stateful one:
import React, { Component, PropTypes } from 'react';
import { View, Text, StyleSheet, TouchableHighlight } from 'react-native';
import * as globalStyles from '../styles/global';
export default class Square extends Component {
render() {
const { square, textStyle, squareActive } = styles;
const { sqValue } = this.props;
return (
<TouchableHighlight
style={[square, sqValue[1] && squareActive]}
onPress={() => console.log(sqValue[0])}
>
<View>
<Text style={textStyle}>{sqValue[0]},{sqValue[1]}</Text>
</View>
</TouchableHighlight>
);
}
}
I'd like to dispatch an action from onPress={}. Thank you