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

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.

Related

example of react-native multi-select with formik

Does anybody have a working example of a react-native multi-select with formik? I already tried
import SectionedMultiSelect from 'react-native-sectioned-multi-select';
but the value array doesn't get submitted, but instead get an empty array.
Thank you.
there you have, hope you're reading the docs for both libraries. I'm doing that and it was just joining the code. it should work.
// Formik x React Native example
import React from 'react';
import { Button, TextInput, View } from 'react-native';
import { Formik } from 'formik';
import Icon from 'react-native-vector-icons/MaterialIcons';
import SectionedMultiSelect from 'react-native-sectioned-multi-select';
const items = [
{
name: 'Fruits',
id: 0,
// these are the children or 'sub items'
children: [
{ name: 'Apple', id: 10 },
{ name: 'Strawberry', id: 17 },
],
},
];
export const MyReactNativeForm = props => (
<Formik
initialValues={{ items: [] }}
onSubmit={values => console.log(values)}
>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View>
<SectionedMultiSelect
items={items}
IconRenderer={Icon}
uniqueKey="id"
subKey="children"
selectText="Choose some things..."
showDropDowns={true}
readOnlyHeadings={true}
onSelectedItemsChange={handleChange('items')}
selectedItems={values.items}
/>
<Button onPress={handleSubmit} title="Submit" />
</View>
)}
</Formik>
);
this is the example
import React, { Component } from 'react';
import { View } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';
import SectionedMultiSelect from 'react-native-sectioned-multi-select';
const items = [
// this is the parent or 'item'
{
name: 'Fruits',
id: 0,
// these are the children or 'sub items'
children: [
{
name: 'Apple',
id: 10,
},
{
name: 'Strawberry',
id: 17,
},
{
name: 'Pineapple',
id: 13,
},
{
name: 'Banana',
id: 14,
},
{
name: 'Watermelon',
id: 15,
},
{
name: 'Kiwi fruit',
id: 16,
},
],
},
{
// next parent item
...
},
];
export default class App extends Component {
constructor() {
super();
this.state = {
selectedItems: [],
};
}
onSelectedItemsChange = (selectedItems) => {
this.setState({ selectedItems });
};
render() {
return (
<View>
<SectionedMultiSelect
items={items}
IconRenderer={Icon}
uniqueKey="id"
subKey="children"
selectText="Choose some things..."
showDropDowns={true}
readOnlyHeadings={true}
onSelectedItemsChange={this.onSelectedItemsChange}
selectedItems={this.state.selectedItems}
/>
</View>
);
}
}

A bit confuse about react ContextAPI passing an array state

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 !

The array for multi select drop down is not referenced well and gives an error

I am trying to use a multi select drop down as explained here but one way or the other the items array is not properly defined.
This is my code for the friendselector component:
/* eslint-disable react-native/no-inline-styles */
import React, {Component} from 'react';
import {View} from 'react-native';
import MultiSelect from 'react-native-multiple-select';
export default class FriendSelector extends Component {
constructor() {
super();
this.state = {
selectedItems: [],
items: [
{
id: '92iijs7yta',
name: 'Kenneth',
},
{
id: 'a0s0a8ssbsd',
name: 'Ann',
},
{
id: '16hbajsabsd',
name: 'Leen',
},
{
id: 'nahs75a5sg',
name: 'Kris',
},
{
id: '667atsas',
name: 'Steve',
},
{
id: 'suudydjsjd',
name: 'Sarah',
},
],
};
}
onSelectedItemsChange = selectedItems => {
this.setState({selectedItems});
};
render() {
const {selectedItems} = this.state;
return (
<View>
<MultiSelect
hideTags
items={this.items}
uniqueKey="id"
ref={component => {
this.multiSelect = component;
}}
onSelectedItemsChange={this.onSelectedItemsChange}
selectedItems={selectedItems}
selectText="Pick friend(s)"
searchInputPlaceholderText="Search..."
onChangeInput={text => console.log(text)}
tagRemoveIconColor="#CCC"
tagBorderColor="#CCC"
tagTextColor="#CCC"
selectedItemTextColor="#CCC"
selectedItemIconColor="#CCC"
itemTextColor="#000"
displayKey="name"
searchInputStyle={{color: '#CCC'}}
submitButtonColor="#CCC"
submitButtonText="Submit"
/>
<View>
{this.multiSelect &&
this.multiSelect.getSelectedItemsExt(selectedItems)}
</View>
</View>
);
}
}
which is similar as in this tutorial, I did change some references to items with state - this to connect things to one another. Still the items are not loaded in items={this.items} I have the feeling.
Does anyone know why?
This is the error:
Thanks for your answer!
items prop is getting an undefined value because it's assigned this.items which doesn't exist in your class.
Change items={this.items} to items={this.sate.items} it makes more sense.
Another solution is to declare items array outside of the state.

How to add a "reset values" button to a react-admin edit form

Is there a way to have a button in a react-admin form so that when I click the button, the values are reset to the edited record's initial values?
I don't mean a Cancel button (that would close the form and redirect). I mean a reset-to-initial-values button that would discard any changes from the last save.
New implementation related to replacing 'redux-form 'with' react-final-form':
import React, {
useCallback,
} from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { Button } from 'react-admin'
import { useForm } from 'react-final-form'
import { makeStyles } from '#material-ui/core/styles'
import IconClear from '#material-ui/icons/Clear'
const useStyles = makeStyles(theme => ({
button: {
marginLeft: '10px',
position: 'relative',
},
leftIcon: {
marginRight: theme.spacing(1),
},
icon: {
fontSize: 18,
},
}), { name: 'ClearButton' })
const sanitizeRestProps = ({
basePath,
invalid,
pristine,
//reset,
saving,
submitOnEnter,
handleSubmit,
handleSubmitWithRedirect,
undoable,
onSave,
...rest
}) => rest
const ClearButton = ({ className, icon, ...rest}) => {
const classes = useStyles()
const form = useForm()
const handleClick = useCallback(() => {
form.setConfig('keepDirtyOnReinitialize', false)
form.reset()
form.setConfig('keepDirtyOnReinitialize', true)
}, [form])
return (
<Button
className={classnames(classes.button, className)}
onClick={handleClick}
{...sanitizeRestProps(rest)}
>
{ icon ? React.cloneElement(icon, { className: classnames(classes.leftIcon, classes.icon) }) : null }
</Button>
)
}
ClearButton.propTypes = {
className: PropTypes.string,
classes: PropTypes.object,
icon: PropTypes.element,
}
ClearButton.defaultProps = {
icon: <IconClear />,
label: 'Clear',
}
export default ClearButton

Navigation using 'react-native-navigation'

I have created app using 'react-native-navigation' and first navigation working fine.
Navigation.startSingleScreenApp({
screen: {
screen: 'drawer.HomeScreen',
title: '',
navigatorStyle: {
navBarHidden: true
}
}
});
I got issue in navigation
import { Navigation } from 'react-native-navigation';
and tried to navigate using
Navigation.push({
component: {
name: 'drawer.DashboardScreen'
}
});
startMainTab.js
const startTabs = () => {
Promise.all([
Icon.getImageSource("ios-share-alt", 30),
Icon.getImageSource("ios-menu", 30)
]).then(sources => {
Navigation.startTabBasedApp({
tabs: [{
screen: 'drawer.AnalyticsScreen',
navigatorButtons: {
leftButtons: [{
icon: sources[1],
title: "Menu",
id: 'sideDrawerToggle'
}]
}
},
{
screen: 'drawer.DashboardScreen',
navigatorButtons: {
leftButtons: [{
icon: sources[1],
title: "Menu",
id: 'sideDrawerToggle'
}]
}
}
],
drawer: {
left: {
screen: 'drawer.SideDrawer'
}
}
});
});
}
SideDrawer.js
export default startTabs;
export default class SideDrawer extends Component {
constructor(props) {
super(props);
this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
}
componentWillMount() {
this.props.navigator.setOnNavigatorEvent(this.onNavigationEvent)
}
onNavigationEvent = (event) => {
// handle a deep link
if (event.type == 'DeepLink') {
const parts = event.link;
alert("Scree: " + parts)
//this.navigateToAbout()
this.props.navigator.push({
screen: "drawer.HomeScreen"
})
if (parts == 'drawer.DashboardScreen') {
//this.onPressScreen1();
}
}
}
navigateToAbout = () => {
this.props.navigator.push({
screen: 'drawer.DashboardScreen'
})
}
render() {
return ( <
View style = {
styles.container
} >
<
Text > SideDrawer < /Text> <
TouchableHighlight onPress = {
this.navigateToAbout.bind(this)
} >
<
Text > Click Me < /Text> <
/TouchableHighlight> <
/View>
)
}
}
Since pushing a screen is an action you perform on an existing navigation stack, you need to call it on your current component navigator object which you'll automagically get as a prop:
this.props.navigator.push({screen: 'drawer.DashboardScreen'})
I strongly suggest you migrate to react-native-navigation v2 as v1 has limited functionality and is no longer maintained.
Download source code from here(React Native Navigation)
App.js:
import React, {Component} from 'react';
import {createStackNavigator,createAppContainer} from 'react-navigation'
import HomeScreen from './Screens/HomeScreen';
import ProfileScreen from './Screens/ProfileScreen';
import ContactScreen from './Screens/ContactScreen';
import MainScreen from './Screens/MainScreen'
export default class App extends Component {
render() {
return <AppNavigationContainer/>
}
}
const AppNavigator = createStackNavigator({
Main:MainScreen,
Home: HomeScreen,
Profile: ProfileScreen,
Contact:ContactScreen
}, {
initialRouteName: 'Main',
navigationOptions: {
headerTitleStyle: {
fontWeight: "bold",
color: "red",
},
headerTintColor: "red"
}
})
const AppNavigationContainer = createAppContainer(AppNavigator);
MOVE FROM ONE SCREEN TO ANOTHER:
this.props.navigation.navigate('Profile')
Thanks!