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);
};
Related
There are four components on a screen and only three out of four are rendering. <popDown/> is the component that isn't rendering. When I save the specific component's file the components get rendered. Note: I am saving an already fully updated file. It is running with no errors
The Screen
import react from 'react';
import {View,ScrollView} from 'react-native';
import { SafeAreaView, } from 'react-navigation';
import { PrProvider } from '../appFunctions/PrContext';
import PopDown from '../Components/PRForm/popDown';
import RepsWeightTextInput from '../Components/PRForm/RepsWeightTextInput';
import NotesInput from '../Components/PRForm/NotesInput';
import SubmitPr from '../Components/PRForm/SubmitPr';
const PrEnteryScreen = ({}) => {
return(
<View style = {{height:'100%',width:'100%',backgroundColor:'#141212'}}>
<SafeAreaView style = {{alignItems:'center'}}>
{/**
* use context for pr information
*/}
<PrProvider>
<PopDown />
<RepsWeightTextInput/>
<NotesInput/>
<SubmitPr/>
</PrProvider>
</SafeAreaView>
</View>
);
};
export default PrEnteryScreen;
popdown component
import { useContext, useEffect, useState } from "react";
import { TouchableOpacity,StyleSheet,View,LayoutAnimation,UIManager,Platform,useFocusEffect } from "react-native";
import { Children } from "react/cjs/react.production.min";
import SelectExerciseButton, { setIsOpen } from "./SelectExerciseButton";
import SelectExerciseModal from "../../Screens/SelectExerciseModal";
import { EXERCISE_DATA } from "../../Screens/SelectExerciseModal";
import { PrContext, PrProvider } from "../../appFunctions/PrContext";
if (
Platform.OS === "android" &&
UIManager.setLayoutAnimationEnabledExperimental
) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
const PopDown = () => {
const value = useContext(PrContext)
const [isOpen,setIsOpen] = useState(false)
const [listHeight,setListHeight] = useState(0)
const [textName,setTextName] = useState(value.exercise);//eventually want to change text based on exercise state
const toggleOpen = () => {
setIsOpen(value => !value);
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
setTextName(value.exercise);
console.log(value.exercise);
}
useEffect(() =>{
EXERCISE_DATA.forEach(()=>{
setListHeight(value => value+50)
})
},[isOpen])
return(
<>
<TouchableOpacity
onPress = {toggleOpen}
>
<SelectExerciseButton />
</TouchableOpacity>
<View>
<SelectExerciseModal style = {isOpen ? styles.show: styles.hidden} listHeight = {listHeight} name = {textName}/>
</View>
</>
)
}
const styles = StyleSheet.create({
hidden:{
height:0,
},
show:{ backgroundColor: '#9B9A9A', width: 200 }
});
export default PopDown;
What I tried
I changed the hidden style height to see if it would render the list that is supposed to pop out of the button. The list did render which means the <selectExerciseButton/> is the only thing not rendering in <popDown/>.
const styles = StyleSheet.create({
hidden:{
height:100,
},
show:{ backgroundColor: '#9B9A9A', width: 200 }
});
<TouchableOpacity
onPress = {toggleOpen}
>
{children}
</TouchableOpacity>
<View>
<SelectExerciseModal style = {isOpen ? styles.show: styles.hidden} listHeight = {listHeight} name = {textName}/>
</View>
<PrProvider>
<PopDown>
<SelectExerciseButton/>
</PopDown>
<RepsWeightTextInput/>
<NotesInput/>
<SubmitPr/>
</PrProvider>
SelectExerciseButton
import { useNavigation,useFocusEffect } from "#react-navigation/native";
import { SafeAreaView, StyleSheet, Text, TouchableOpacity, View,LayoutAnimation } from "react-native";
import { useContext, useState,useEffect } from "react";
import { PrContext } from "../../appFunctions/PrContext";
/**
*
* #returns button that navigates to the a modal to select an exercise
*/
if (
Platform.OS === "android" &&
UIManager.setLayoutAnimationEnabledExperimental
) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
const SelectExerciseButton = () => {
const value = useContext(PrContext)
return(
<>
<View style = {styles.background}>
<Text style = {styles.Text}> {value.exercise} </Text>
</View>
</>
);
};
styles = StyleSheet.create({
background:{
backgroundColor: '#9B9A9A',
width: 335,
borderRadius:41,
alignItems:'center',
marginHorizontal:25,
height:200,
justifyContent:'center'
},
Text:{
fontWeight:'bold',
fontSize:40,
color:'white',
alignItems:'center'
}
})
export default SelectExerciseButton;
Here is my code:
if(refRBSheet.current?.open()){
refRBSheet.current.close();
}
In my React Native application I am implementing 'react-native-raw-bottom-sheet'. I want to check if the RBSheet is open, and if it is then I want to close it. The above code open's the RBSheet instead of closing.
As mentioned in the library documentation, it supports onOpen and onClose event functions. Use them to save the open/closed state of the bottom sheet.
import React, { useState, useRef } from 'react';
import { StyleSheet, SafeAreaView, View, Button } from 'react-native';
import RBSheet from 'react-native-raw-bottom-sheet';
const App = () => {
const [open, setOpen] = useState(false);
const refRBSheet = useRef();
const onPress = () => {
if (!open) {
refRBSheet.current.open();
} else {
refRBSheet.current.close();
}
};
return (
<SafeAreaView>
<View>
<Button title="Open" onPress={onPress} />
</View>
<RBSheet
ref={refRBSheet}
onOpen={() => setOpen(true)}
onClose={() => setOpen(false)}
// .....
>
<Button title="Close" onPress={onPress} />
</RBSheet>
</SafeAreaView>
);
};
Assume the fetch returns an object of 150 items, of this 150 items only 20 are rendered as components. I've tried FlatList, LargeList and have watched multiple youtube videos and can't seem to get it to work.
I run this on the Expo Dev app, and when I scroll to the bottom of the list, no more load. Only about 20 cards are rendered.
This is what the end of the screen looks like, I try scroll down more and no more load.
Screen shot when scrolling to the bottom:
Screen shot after scrolling to the bottom:
This is the code for my home screen:
import React, { useEffect, useState } from 'react';
import {StyleSheet, ScrollView, Alert, ActivityIndicator} from 'react-native';
import HeaderTabs from '../components/HeaderTabs';
import Screen from '../components/Screen'
import Categories from '../components/Categories'
import SearchBar from '../components/SearchBar'
import ServiceItem from "../components/ServiceItem";
import tailwind from 'tailwind-react-native-classnames';
import { localServices } from '../data/localServices';
import colors from '../configs/colors'
const YELP_API_KEY = "RF2K7bL57gPbve8oBSiX23GYdCVxIl-KedmS-lyEafEZKNIn6DgsN6j88JvHolhiT4LH-VxT2NvDwgzl9yCTW-5REbbu3Cl5vwqCNUtGhnzzScPinQciOvs6PVBtY3Yx";
const HomeScreen = () => {
const [serviceData, setServiceData] = useState(localServices)
const [city, setCity] = useState("San Francisco")
const [activeTab, setActiveTab] = useState("Delivery");
const [loading, setLoading] = useState(false)
const getServicesFromYelp = () => {
const yelpUrl = `https://api.yelp.com/v3/businesses/search?term=Home+Services&location=${city}`;
const apiOptions = {
headers: {
Authorization: `Bearer ${YELP_API_KEY}`,
},
};
setLoading(true)
return fetch(yelpUrl, apiOptions)
.then((res) => res.json())
.then((json) => {
setLoading(false)
if(json.error) return Alert.alert('Sorry', json.error.description);
setServiceData(
json?.businesses?.filter((business) =>
// business.transactions.includes(activeTab.toLowerCase())
business
// city.includes(business.location.city)
)
)
}
);
};
useEffect(() => {
getServicesFromYelp();
}, [city, activeTab]);
return (
<Screen style={tailwind`bg-white flex-1`}>
<HeaderTabs activeTab={activeTab} setActiveTab={setActiveTab} />
<SearchBar setCity={setCity} city={city} />
<ScrollView style={tailwind`flex-1`} showsVerticalScrollIndicator={false}>
<Categories />
{loading && <ActivityIndicator size="large" color={colors.primary} style={tailwind`mt-2 mb-6`} />}
<ServiceItem serviceData={serviceData} />
</ScrollView>
</Screen>
);
}
const styles = StyleSheet.create({})
export default HomeScreen;
This is the code for the individual components:
ServiceItem.js:
import React from 'react';
import { View } from 'react-native';
import ServiceItemCard from "./ServiceItemCard";
const ServiceItem = ({ serviceData }) => {
return (
<View>
{serviceData?.map((item, index) => (
<ServiceItemCard key={index} item={item} />
))}
</View>
);
}
export default ServiceItem;
ServiceItemCard.js:
import React, { useState } from 'react';
import { Image, Text, TouchableOpacity, View, FlatList } from 'react-native';
import tailwind from 'tailwind-react-native-classnames';
import { Entypo } from '#expo/vector-icons';
import { MaterialCommunityIcons } from '#expo/vector-icons';
const ServiceItemCard = ({ item }) => {
const [loved, setLoved] = useState(false)
return (
<View style={tailwind`mx-4 mb-4`}>
<Image
source={{ uri: item.image_url ? item.image_url : null}}
style={tailwind`w-full h-48 rounded-lg`}
/>
<TouchableOpacity style={tailwind`absolute top-2 right-2`} onPress={() => setLoved(e => !e)}>
<Entypo name={`${loved ? 'heart' : 'heart-outlined'}`} size={28} color="#fff" />
</TouchableOpacity>
<View style={tailwind`flex-row items-center mt-1`}>
<View style={tailwind`flex-grow`}>
<Text style={tailwind`font-bold text-lg`} numberOfLines={1}>{item.name}</Text>
<View style={tailwind`flex-row items-center`}>
<MaterialCommunityIcons name="clock-time-four" size={13} color="#06C167" />
<Text style={tailwind`text-xs text-gray-700`}> 20-30 • min • {item.price}</Text>
</View>
</View>
<View style={tailwind`w-8 h-8 justify-center items-center bg-gray-100 rounded-full`}>
<Text style={tailwind`text-gray-600 text-xs`}>{item.rating}</Text>
</View>
</View>
</View>
)
}
export default ServiceItemCard;
I tried using FlatList, LargeList and messing around with infinite scrolling
I got stuck here ,
I needed to make a counter into the textinput ,
and I realize ,the counter has conflict with the handleChange.
I have no idea how to modify it ,could you please take a look at my code ?Thank you so much in advance !!
import { StyleSheet, View } from 'react-native'
import React from 'react'
import AppForm from '../components/AppForm'
import * as Yup from 'yup'
import AppFormFieldWithCount from '../components/AppFormFieldWithCount';
const validationSchema = Yup.object().shape({
userName: Yup.string().required("Username can't be empty").label("Username"),
});
const EditScreen = () => {
const handleSubmit = async (userInfo) => {
console.log("receive information",userInfo);
};
return (
<View style={styles.container}>
{/** <TextInputWithCount number={12} maxLength={12} multiline={false} placeholder={"用户名"}/> */}
<AppForm
initialValues={{userName:''}}
validationSchema ={validationSchema}
onSubmit = {handleSubmit}
>
<AppFormFieldWithCount
name = {'userName'}
number ={15}
placeholder={"Username"}
maxLength ={15}
multiline={false}
/>
</AppForm>
</View>
)
}
export default EditScreen
const styles = StyleSheet.create({
container:{
padding:30,
}
})
Below ,it is the formik TextInput :
I have added the setValue for counting the text ,but the textinput will need the handleChange for getting the textinput information .Therefore, it has the conflict here, only one of them works in onChangeText function ...
import { StyleSheet, Text, View,TextInput} from 'react-native'
import React,{useState} from 'react'
import TextInputWithCount from './TextInputWithCount'
import AppErrorMessage from './ErrorMessage'
import { useFormikContext } from 'formik';
import colors from '../config/colors';
const AppFormFieldWithCount = ({name,number,maxLength,multiline,placeholder,...otherProps}) => {
const {setFieldTouched,handleChange,errors,touched} = useFormikContext();
const[value,setValue] = useState('');
return (
<>
<View style={styles.container}>
<TextInput placeholder={placeholder}
style={{flex:1,fontSize:18}}
placeholder = {placeholder}
multiline={multiline}
maxLength={maxLength}
onBlur = {()=>setFieldTouched(name)}
onChangeText = {
handleChange(name)
}
{...otherProps}
/>
<Text>{value === "" ? "0" : value.length}/{number}</Text>
</View>
<AppErrorMessage error={errors[name]} visible={touched[name]} />
</>
)
}
export default AppFormFieldWithCount
const styles = StyleSheet.create({
container:{
flexDirection:'row',
borderRadius:5,
borderWidth:1,
borderColor:colors.medium,
alignItems:'center',
width:'100%',
paddingHorizontal:10,
}
})
Icons are not displaying in HeaderButtons. Instead the text given for fallback is displaying only.
Here is my Code for component:
import React from "react";
import { Platform } from "react-native";
import { HeaderButton } from 'react-navigation-header-buttons';
import { Ionicons } from 'react-native-vector-icons';
import Colors from '../constants/Colors';
const CustomHeaderButton = props => {
return (
<HeaderButton
{...props}
IconComponent={Ionicons}
iconSize={23}
color={Platform.OS === "android" ? "white" : Colors.primaryColor}
/>
);
};
export default CustomHeaderButton;
Here is the file in which I imported it:
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
import { MEALS } from '../data/dummy-data';
import HeaderButton from '../components/HeaderButton';
const MealDetailScreen = props => {
const mealId = props.navigation.getParam("mealId");
const selectedMeal = MEALS.find(meal => meal.id === mealId);
return (
<View style={styles.screen}>
<Text>{selectedMeal.title}</Text>
<Button title="Go back to Categories!" onPress={() => {
props.navigation.popToTop();
}} />
</View>
);
}
MealDetailScreen.navigationOptions = (navigationData) => {
const mealId = navigationData.navigation.getParam("mealId");
const selectedMeal = MEALS.find(meal => meal.id === mealId);
return {
headerTitle: selectedMeal.title,
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Favorite"
iconName="star"
onPress={() => {
console.log("Mark as favorite.");
}}
/>
</HeaderButtons>
)
};
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: "center",
alignItems: "center",
// backgroundColor: "white"
}
});
export default MealDetailScreen;
It is not giving any error and giving the output in console. But icon for star is not displaying.
add the below code in android/app/build.gradle and re-run the app.
project.ext.vectoricons = [
iconFontNames: [ 'Ionicons.ttf' ] // Name of the font files you want to
copy
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
I got the error.
Instead of this:
import { Ionicons } from 'react-native-vector-icons';
I added this:
import Ionicons from 'react-native-vector-icons/Ionicons';
and icon appeared.
Hi there you can fix this issue by navigating to the android/app/build.gradle
and paste this line at the top and re-run the app by react-native run-android
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"