Why doesn't checkbox work in React Native? - react-native

import CheckBox from '#react-native-community/checkbox';
export default class All extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [],
isSelected: true,
};
}
checkBoxChanged() {
alert('changed');
this.setState({isSelected : !this.state.isSelected})
}
render() {
const { items } = this.state;
return (
<Content>
<View>
{items.map((item) => (
<View>
<Text>{item.name}</Text>
<CheckBox
value={this.state.isSelected}
onValueChange={() => this.checkBoxChanged()}
/>
</View>
))}
</View>
</Content>
);
}
}
This doesn't work.I mean nothing happens.
When I check on, nothing changes and it doesn't reach to checkBoxChanged().
I got stuck in this problem.
I would appreciate it if you could help me :)

You can use onValueChange={() => checkBoxChanged()}
<CheckBox
value={this.state.isSelected}
onValueChange={() => checkBoxChanged()}
/>
And in checkBoxChanged function you can set the state to change the value of isSelected
checkBoxChanged(){
this.setState({isSelected : !this.state.isSelected})
}
Moreover the checkbox has been deprecated you have to install
#react-native-community/checkbox
check this link to know more.
Hope this helps

import { CheckBox } from 'react-native';
isChecked = false
checkBoxChanged() {
alert('changed');
}
getCheckedStatus(){
this.isChecked != this.isChecked;
return this.isChecked;
}
<CheckBox
activeOpacity={1}
textStyle={{ color: colors.colorGray, fontSize: dimen.fontSize.textAppearanceBody1_16 }}
containerStyle={styles.checkBoxContainer}
checkedColor={colors.profileTabSelectedColor}
uncheckedColor={colors.profileTabSelectedColor}
title={'Gender'}
checked={this.getCheckedStatus()}
onPress={() => { this.checkBoxChanged() }}
/>

I would like to tell you don't use checkbox from react-native it is deprecated, still if you are using it please see the below code, there is no onChange Prop, use onValueChange instead of onChange, and maintain a state and pass value prop to checkbox component.
https://reactnative.dev/docs/checkbox#__docusaurus
import React, { useState } from "react";
import { CheckBox, Text, StyleSheet, View } from "react-native";
export default App = () => {
const [isSelected, setSelection] = useState(false);
return (
<View style={styles.container}>
<View style={styles.checkboxContainer}>
<CheckBox
value={isSelected}
onValueChange={setSelection}
style={styles.checkbox}
/>
<Text style={styles.label}>Do you like React Native?</Text>
</View>
<Text>Is CheckBox selected: {isSelected ? "👍" : "👎"}</Text>
</View>
);
};

The code should be
import { CheckBox } from 'react-native';
checkBoxChanged() {
alert('changed');
}
<CheckBox onValueChange={()=>this.checkBoxChanged()} />
You are calling the function directly instead of calling it on click.
This checkbox works only in Android so better use the one from react-native elements
https://react-native-elements.github.io/react-native-elements/docs/checkbox.html

Checkbox are being deprecated from react-native-element but it can be used from react native component.
to use them.
Install : npm install #react-native-community/checkbox --save
Usage:
import CheckBox from '#react-native-community/checkbox';
Inside you use this element
<CheckBox value={this.state.check}
onChange={()=>this.checkBoxText()} />
And inside your class
constructor(props) {
super(props);
this.state = {
check: false
};
Declare a function outside your constructor area.
create:
checkBoxText() {
this.setState({
check:!this.state.check
})
alert("Value Changed to " + this.state.check)
}
It will create your clickable Check-box on your application.

Related

react hook form multiple control on one Controller

I have a text input component that uses text input from react native paper, I want to make a place autocomplete by calling google place autocomplete API
right now I can display the suggestion but I can't change the text input value with the value of the suggestion that has been clicked
screenshot of component
since I use Controller from react hook form I thought I could use setValue from useForm to change the value but it didn't do anything when I try to call setValue to change textInput value to one of the suggested value
import React from "react";
import { FlatList, StyleSheet, TouchableOpacity, View } from "react-native";
import { Text, TextInput, Colors } from "react-native-paper";
import { Controller, useForm } from "react-hook-form";
import axiosInstance from "services/axiosInstance";
export default React.forwardRef(
(
{
name,
label,
placeholder,
control,
style: addOnStyle,
...props
},
ref
) => {
const { setValue } = useForm();
const [addressList, setAddressList] = React.useState([])
const getAddressList = async (input) => {
if (input == null || input.match(/^ *$/) !== null) {
setAddressList([])
} else {
const response = await axiosInstance.get(
`https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${input}&components=country:us&language=en&key=API_KEY`
)
setAddressList([])
if (response?.data?.status === "OK") {
response?.data?.predictions?.map((item) => setAddressList(addressList => [...addressList, item.description]))
} else {
setAddressList(["Address not found."])
}
}
}
return (
<View style={{ ...styles.viewInput, ...addOnStyle }}>
<Controller
control={control}
name={name}
defaultValue=""
render={({
field: { onChange, onBlur, value, name },
fieldState: { error },
}) => {
return (
<>
<TextInput
label={label}
name={name}
placeholder={placeholder}
onBlur={onBlur}
onChangeText={(val) => onChange(val, getAddressList(val))}
error={!!error?.message}
value={value}
ref={ref}
{...props}
/>
{error?.message ? (
<Text style={styles.textError}>{error?.message}</Text>
) : null}
{addressList.length > 0 ?
<View style={styles.addressListContainer}>
<FlatList
keyExtractor={(_, i) => String(i)}
data={addressList}
renderItem={({ item, index }) => {
return (
<TouchableOpacity
activeOpacity={1}
style={[styles.addressListItem, index==0 ? {borderTopWidth: 0} : {borderTopWidth: 1}]}
onPress={() => {setAddressList([]), setValue(name, item)}}
>
<Text numberOfLines={1}>{item}</Text>
</TouchableOpacity>
)
}}
/>
</View>
: null}
</>
);
}}
/>
</View>
);
}
);
UPDATE Changed the title to match the current question
I think for now my problem is since the control is set from the outside of the component that makes it can't be changed with setValue from inside the component, now I wonder if we could use multiple control on one Controller?
I solve it by changing setValue(name, item) on onPress to onChange(item) it doesn't need another control

React checkbox check, but doesn't uncheck

I'm creating app in React Native and I need checkbox there. I can check a checkbox, but I cannot uncheck it.
I'm using state to know, if it's checked/unchecked.
import { CheckBox } from 'react-native';
this.state = {
checked: false,
}
<CheckBox value={this.state.checked} onValueChange={() => this.setState({ checked: !this.state.checked })} />
I was expecting, that this.setState({ checked: !this.state.checked })} will negate this.state.checked but it's doesn't seems like that.
This code is working for me.
import * as React from 'react';
import { Text, View, CheckBox } from 'react-native';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
checked: false
};
}
render() {
return (
<View>
<CheckBox
value={this.state.checked}
onValueChange={() => this.setState({ checked: !this.state.checked })}
/>
</View>
);
}
}
I dont know from where are you imported that checkbox, but for example: https://react-native-training.github.io/react-native-elements/docs/checkbox.html
This needs a prop checked, but not a prop value
In your case:
<CheckBox checked={this.state.checked} onValueChange={() => this.setState({ checked: !this.state.checked })} />

Navigation.getParam is undefined while trying to pass function as parameter

I'm trying to use a function from my Main component in my details component which I user react navigation to navigate to and I want to save some changes in detail screen in my main component
//Main.js
import React from 'react';
import {
StyleSheet ,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity,
KeyboardAvoidingView,
AsyncStorage
} from 'react-native'
import Note from './Note'
import { createStackNavigator, createAppContainer } from "react-navigation";
import Details from './Details';
export default class Main extends React.Component {
static navigationOptions = {
title: 'To do list',
headerStyle: {
backgroundColor: '#f4511e',
},
};
constructor(props){
super(props);
this.state = {
noteArray: [],
noteText: ''
};
}
render() {
let notes = this.state.noteArray.map((val,key) => {
return <Note key={key} keyval={key} val={val}
goToDetailPage= {() => this.goToNoteDetail(key)}
/>
});
const { navigation } = this.props;
return(
<View style={styles.container}>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<Details saveEdit={this.saveEdit} />
</View>
);
}
goToNoteDetail=(key)=>{
this.props.navigation.navigate('DetailsScreen', {
selectedTask: this.state.noteArray[key],
saveEdit: this.saveEdit
});
}
saveEdit = (editedTask,dueDate) => {
this.state.noteArray.push({
'creationDate': editedTask['creationDate'],
'taskName': editedTask['taskName'],
'dueDate': dueDate
});
this.setState({noteArray:this.state.noteArray})
this.saveUserTasks(this.state.noteArray)
}
this.setState({noteArray:this.state.noteArray})
this.saveUserTasks(this.state.noteArray)
}
}
Then I try to use it as prop in my Detail.js
import React from 'react';
import {
StyleSheet ,
Text,
View,
TextInput,
Button,
TouchableOpacity,
} from 'react-native'
import { createStackNavigator, createAppContainer } from "react-navigation";
export default class Details extends React.Component {
constructor(props){
super(props);
this.state = {
dueDate = ''
}
}
static navigationOptions = {
headerStyle: {
backgroundColor: '#f4511e',
},
};
componentDidMount = () => {
this.getUserTasks()
}
render() {
const { navigation } = this.props;
const selectedTask = navigation.getParam('selectedTask', 'task');
var { saveEdit} = this.props;
return(
<View key={this.props.keyval} style={styles.container}>
<View style = { styles.info}>
<Text style= {styles.labelStyle}> Due date:
</Text>
<TextInput
onChangeText={(dueData) => this.setState({dueData})}
style={styles.textInput}
placeholder= {selectedTask['dueDate']}
placeholderTextColor='gray'
underlineColorAndroid = 'transparent'
>
</TextInput>
</View>
<TouchableOpacity onPress={this.props.saveEdit(selectedTask, this.state.dueDate)} style={styles.saveButton}>
<Text style={styles.saveButtonText}> save </Text>
</TouchableOpacity>
</View>
);
}
}
I searched a lot to find the solution and I tried many of them but get different undefined errors. This is not what I did in the first place but when I search I found this solution here. And I know it causes lots of issues.
I want to know how can I manage to access to main method from details and pass parameters to it or how can I manage to use main props in my details component
If you are using react-navigation 5, params is no longer under the navigation object but under route object. This is the link to the sample code:
https://reactnavigation.org/docs/params
Solution
<Details saveEdit={this.saveEdit} />
to
<Details navigation={this.props.navigation} saveEdit={this.saveEdit} />
render() {
return(
<View style={styles.container}>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<Details navigation={this.props.navigation} saveEdit={this.saveEdit} />
</View>
);
}
Why?
You are using your Details component in Main screen. So you need to give navigation to Details's props from your Main to use navigation props in Details component.
Because your Details component is not the screen component registered in your navigator(router).
I tried to run your code on my machine but it seems you have too many syntax error in your code (maybe because of copy pasta?)
but it seems you should change
<TouchableOpacity onPress={this.props.saveEdit(selectedTask, this.state.dueDate)}
in Detals.js to
<TouchableOpacity onPress={this.props.navigation.getParams('saveEdit')(selectedTask, this.state.dueDate)}
for clarification this worked for me
in MainPage.js
_test(){
console.log('test');
}
.
.
.
<ActionButton
buttonColor="rgba(231,76,60,1)"
onPress={() => NavigationService.navigate('AddNewSession', {test: this._test})}>
</ActionButton>
and in AddNewSession.js
componentDidMount()
let test = this.props.navigation.getParam('test');
test();
}
There are many mistakes within your codes. First of all you are importing the navigation build-in function {createStackNavigator} in all your files, Main.js and Details.js :
import { createStackNavigator, createAppContainer } from
"react-navigation";
That make me think that you didn't know how the stack navigation or navigation in general functions in react native. You should have a file that handles your routes configuration, let call it MyNavigation.js and then define the routes 'Main' and 'details' in MyNavigations,js. It's only inside MyNavigation.js that you can import "createStackNavigator". Then you will define your functions to move between the screens "Main" and "detail". Those functions will be passed as props to the routes when moving between one another. The overall action wihtin MyNavigation.js will look like:
import React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import Main from './Main';
import Detail from './Detail';
const Stack = createStackNavigator();
function goToDetailFromMainScreen(){
return(this.props.navigation.navigate('switch2'));
}
function DetailSaves(){
return(//your code here to save details);
}
//Here you pass the functions to Main Component to handele Detail componets
's actions
function switch1(){
return(<Main GoToDetails={() => this.goTodetailFromMainScreen()} paramsForDetailActions={() => this.detailSaves()} />)
}
function switch2(){
return(<Details />)
}
export default function MyNavigation() {
return(
<NavigationContainer>
<Stack.Navigator initialRouteName='switch1'>
<Stack.Screen name='switch1' options={{header:()=>null}} component={Main} />
<Stack.Screen name='switch2' options={{headerTitle:"Detail"}} component={Detail} />
</Stack.Navigator>
</NavigationContainer>
)
}
Now inside Main.js you check the props functions passed to it from MyNavigation.js:
// Main.js
constructor(props){
super(props);
}
goToDetails = () => {
this.props.onPress?.();
}
paramsForDetailActions= () => {
this.props.onPress?.();
}

In React-native, how to handle checkbox in Listview?

In my react-native app, I am trying to show my contact details with checkboxes for selecting.
Here is my code:
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData, sectionID, rowID) => (
<TouchableHighlight onPress={() => this.goRideDetails(rowData)}>
<Text style={styles.rideHeader}>{rowData.name} </Text>
<CheckBox
checked={this.state.checked}
onCheckBoxPressed={() =>
this.setState({ checked: !this.state.checked })
}
/>
</TouchableHighlight>
)}
/>
In my view checkbox is displaying on every row, but not working.
Any one can help me. Thanks in advance.
You can easily do this with component separation. Please, take a look here:
export default class ContactList extends Component {
static propTypes = {
contacts: React.PropTypes.array,
}
static defaultProps = {
contacts: [],
}
constructor(){
super();
this._renderRow = this._renderRow.bind(this);
}
_renderRow(rowData,sectionID,rowID) {
return <Contact info={ rowData } />;
}
render() {
return (
<ListView
dataSource={ this.props.contacts }
renderRow={ this._renderRow }
/>
);
}
}
export class ContactList extends Component {
static propTypes = {
info: React.PropTypes.object.isRequired,
}
constructor(){
super();
this.goRideDetails = this.goRideDetails.bind(this);
this.setChecked = this.setChecked.bind(this);
}
goRideDetails() {
//your logic here
}
setChecked() {
this.props.info.checked = !this.props.info.checked; //will be much better to do it with redux and action creators
}
render() {
return (
<TouchableHighlight onPress={ this.goRideDetails }>
<Text style={ styles.rideHeader }>{this.props.info.name} </Text>
<CheckBox checked={ this.props.info.checked } onCheckBoxPressed={ this.setChecked } />
</TouchableHighlight>
);
}
}
After that you can simply call:
<ContactList contacts={this.state.dataSource} />
in your jsx and voila.
Important note: Do not use array functions inside your jsx code blocks.
Important note 2: Try to start using redux or flux for storing state of your application. It will be provide much better code design.
Hope, it will help.
import React , {Component} from 'react'
import {
Text,
View,
ListView,
StyleSheet,
TouchableOpacity,
Image,
} from 'react-native'
import CheckBox from 'react-native-checkbox'
var Folder = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
var folder = '' ////// all the new folder
var check_folder = [] ////// all the check box conditions
class ApproveContent extends Component {
///////// all the upper thing that are global variable for this script is has same value as that of the state the only reason we are using this because of the layout update //////////
state={
folder:[],
data:[],
check:[]/////// this need to do just to upadte the layout of the check box
}
render(){
return(
<View style = {{flex:1,backgroundColor:'white',alignItems:'center'}}>
<ListView
dataSource={Folder.cloneWithRows(this.state.folder)}
renderRow={(rowData,rowID,sectionID) => <View style = {{ alignItems: 'center',margin:5}}>
<TouchableOpacity style = {{width:Dimension.ScreenWidth/1.2,height:Dimension.ScreenHeight/6,flexDirection: 'row',alignItems:'center'}}
onPress={() => {}}>
<CheckBox
label=''
labelBefore={false}
checked={this.state.check[sectionID]}
checkboxStyle = {{marginLeft: 20}}
onChange={(checked) => {
this.setState({
check:!this.state.check
})
if(check_folder[sectionID] == false){
check_folder[sectionID] = true
this.setState({
check:check_folder// has to do this because we cant change the single element in the array
})
}else{
check_folder[sectionID] = false
this.setState({
check:check_folder// has to do this because we cant change the single element in the array
})
}
console.log(check_folder)a
}}
/>
</TouchableOpacity>
</View>
}
/>
</View>
)}
}
export default ApproveContent
const style = StyleSheet.create({
TextStyle:{
fontFamily: 'Roboto-Bold',
fontSize:15,
},
approveButton: {
bottom:0,
left:0,
alignItems: 'center',
}
})

How to change state when Button pressed?

I'm new to React Native and unfamiliar with js.
I want the program to show what I wrote in TextInput when I pressed the Button (there's a Text below the Button). I figured maybe I should make two state: put state1 text as Text input, and put state2 mimin as TextInput input, and when Button pressed, put state2 mimin to state1 text.
I've tried with the code below but it gave me Red Page when I click the Button.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Button,
TextInput,
Alert,
View
} from 'react-native';
export default class Hella extends Component {
constructor(props) {
super(props);
this.state = {text: '', mimin: ''};
}
render() {
return (
<View style={styles.container}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(mimin) => this.setState({mimin})}
/>
<Button
onPress={onButtonPress}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
<Text style={styles.instructions}>
{this.state.text}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#F5FCFF',
}
});
const onButtonPress = () => {
Hella.setState({
text: Hella.state.mimin -------> where the error happened
});
};
AppRegistry.registerComponent('Hella', () => Hella);
The error was
undefined is not an object (evaluating 'Hella.state.mimin')
onButtonPress
<project location>/index.android.js:61
What did I do wrong? How should I declare it? Where can I learn more?
Your onButtonPress should be inside class since you want to do setState
export default class Hella extends Component {
constructor(props) {
...
}
onButtonPress = () => {
this.setState({
text: this.state.mimin
});
}
render() {
return (
...
<Button
onPress={this.onButtonPress}
...
/>
...
);
}
}
React Native uses a lot of React concepts. Learning basics of React will help you a lot https://facebook.github.io/react/tutorial/tutorial.html
The function definition should be like below.
onButtonPress = () => {
this.setState({
text: this.state.mimin
});
}