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

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.

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>
);
}
}

Error trying to set up tabs in react-native

I need a hand to correct my code. I want to display a page with 3 tabs with react-native-tab-view and I don't know why I have an error. could you help me find where it's stuck?
What may seem obvious and easy to you may not be easy for me, so please be indulgent :) Thank you very much for your help and your time.
import * as React from 'react';
import { Dimensions } from 'react-native';
import { TabView, SceneMap } from 'react-native-tab-view';
import Information from '../Information';
import Photos from '../Photos';
import Stock from '../Stock';
import { getProducts } from '../../../../src/common/Preferences';
import styles from '../../../../assets/styles';
import i18n from '../../../../src/i18n';
const FirstRoute = () => (
<Information style={styles.scene} />
);
const SecondRoute = () => (
<Stock style={styles.scene} />
);
const ThirdRoute = () => (
<Photos style={styles.scene} />
);
const initialLayout = { width: Dimensions.get('window').width };
export default class ProductDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
// productId: (props.navigation.state.params && props.navigation.state.params.productId ? props.navigation.state.params.productId : -1),
index: 0,
routes: [{ key: '1', title: i18n.t("information.title"),icon: 'ios-paper', }, {icon: 'ios-paper', key: '2', title: i18n.t("stock.title") }, {icon: 'ios-paper', key: '3', title: i18n.t("photos.title") }],
};
}
_handleIndexChange = index => {
this.setState({index})
};
_renderScene = SceneMap({
'1': FirstRoute,
'2': SecondRoute,
'3': ThirdRoute,
});
render() {
return (
<TabView
navigationState={this.state}
renderScene={this._renderScene}
initialLayout={initialLayout}
onRequestChangeTab={this._handleIndexChange}
useNativeDriver
/>
);
};
}
I get :
TypeError: _this.props.onIndexChange is not a function. (In
'_this.props.onIndexChange(index)', '_this.props.onIndexChange' is
undefined)

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

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.

How to call function in map loop (react native)?

This is my code. I am not sure what error exists.
When I click the image button, it calls proper function exactly.
If I click the first button, it calls toggleBooks() function correctly.
Then in that function, I want to use vidMute state value.
So I tried console.log('Video toggle', this.state.vidMute); then it gives me an error like the following image.
But if I print console.log('Video toggle'), then it works well.
How to use state value in that function?
export default class Video extends Component {
constructor(props) {
super(props)
this.state = {
vidMute: false,
audioShow: false,
callShow: false,
btn: [
{ func: this.toggleAudio, url: magic, de_url: de_magic },
{ func: this.endCall, url: endcall, de_url: de_endcall },
{ func: this.toggleBooks, url: camerarotate, de_url: de_camerarotate },
],
};
this.toggleAudio = this.toggleAudio.bind(this)
this.endCall = this.endCall.bind(this)
this.toggleBooks = this.toggleBooks.bind(this)
}
toggleBooks() {
console.log('Video toggle', this.state.vidMute);
}
endCall() {
console.log('Call toggle', this.state.audioShow);
}
toggleAudio() {
console.log('Audio toggle', this.state.callShow);
}
render() {
return (
<View>
{
this.state.btn.map((item, index) => (
<TouchableOpacity key={index} style={styles.iconStyle} activeOpacity={0.4} onPress={item.func}>
<Image source={this.state.lockState ? item.de_url : item.url} style={{ width: 70, height: 70 }} />
</TouchableOpacity>
))
}
</View>
)
}
}
this refers to the context of your function and not the context of your component. You can try to bind your method like this :
this.myMethod = this.myMethod.bind(this);
in your constructor.
Or use the fat arrow pattern (Highly recommanded) which automatically includes the binding to your component's context.
Here is a binding example on stackblitz
Here is the code :
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
name: 'React',
items:[
{name:"item 1", func: () => this.test()},
{name:"item 2", func: () => this.test2()}
]
};
this.test = this.test.bind(this);
}
test() {
console.log('Hi', this.state.name);
}
test2() {
console.log('Hello', this.state.name); // Note this is not binded
}
render() {
return (
<div>
<Hello name={this.state.name} />
<p onClick={this.test}>
Start editing to see some magic happen :)
</p>
<div>
{
this.state.items.map(item => <div onClick={() => item.func()}>{item.name}</div>)
}
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));

How to make dynamic checkbox in react native

I am making a react native application in which i need to make checkbox during runtime.I means that from server i will get the json object which will have id and label for checkbox.Now i want to know that after fetching data from server how can i make checkbox also how can i handle the checkbox , i mean that how many number of checkbox will be there it will not be static so how can i declare state variables which can handle the checkbox.Also how can i handle the onPress event of checkbox.Please provide me some help of code .Thanks in advance
The concept will be using an array in the state and setting the state array with the data you got from the service response, Checkbox is not available in both platforms so you will have to use react-native-elements. And you can use the map function to render the checkboxes from the array, and have an onPress to change the state accordingly. The code will be as below. You will have to think about maintaining the checked value in the state as well.
import React, { Component } from 'react';
import { View } from 'react-native';
import { CheckBox } from 'react-native-elements';
export default class Sample extends Component {
constructor(props) {
super(props);
this.state = {
data: [
{ id: 1, key: 'test1', checked: false },
{ id: 2, key: 'test1', checked: true }
]
};
}
onCheckChanged(id) {
const data = this.state.data;
const index = data.findIndex(x => x.id === id);
data[index].checked = !data[index].checked;
this.setState(data);
}
render() {
return (<View>
{
this.state.data.map((item,key) => <CheckBox title={item.key} key={key} checked={item.checked} onPress={()=>this.onCheckChanged(item.id)}/>)
}
</View>)
}
}
Here's an example how you can do this. You can play with the code, to understand more how it's working.
export default class App extends React.Component {
state = {
checkboxes: [],
};
async componentDidMount() {
// mocking a datafetch
setTimeout(() => {
// mock data
const data = [{ id: 1, label: 'first' }, { id: 2, label: 'second' }];
this.setState({
checkboxes: data.map(x => {
x['value'] = false;
return x;
}),
});
}, 1000);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
{JSON.stringify(this.state)}
</Text>
{this.state.checkboxes.length > 0 &&
this.state.checkboxes.map(checkbox => (
<View>
<Text>{checkbox.label}</Text>
<CheckBox
onValueChange={value =>
this.setState(state => {
const index = state.checkboxes.findIndex(
x => x.id === checkbox.id
);
return {
checkboxes: [
...state.checkboxes.slice(0, index),
{ id: checkbox.id, label: checkbox.label, value },
...state.checkboxes.slice(index+1),
],
};
})
}
value={checkbox.value}
key={checkbox.id}
/>
</View>
))}
</View>
);
}
}