why it is not working to remove if it the same color name? - react-native

I have a problem
My currentColor goes not to null, If I Press a color I set the color to currentColor, if the same color is again pressed then I remove the color (I set currentColor to null). but its not working
const ModalProductSizeColor = forwardRef<BottomSheetModal, IModalProductSizeColor>(({ onPress }, ref) => {
const navigation = useNavigation<NativeStackNavigationProp<RootStackParams>>();
const [currentColor, setCurrentColor] = useState<ColorsOptions | null>(null);
const [sizeScreen, setSizeScreen] = useState<boolean>(false);
const snapPoints = useMemo(() => ['25%', 250], []);
const handleSetCurrentColor = (color: ColorsOptions) => {
console.log(currentColor + 'current in func');
currentColor === color ? setCurrentColor(null) : setCurrentColor(color)
};
console.log(currentColor);
return (
<BottomSheetModal
ref={ref}
index={1}
snapPoints={snapPoints}
handleIndicatorStyle={[s.handleStyle, s.handleColorWhite]}
backdropComponent={BottomSheetBackdrop}
>
<Text style={s.title}>test</Text>
<Colors
colors={ColorsData}
onPress={handleSetCurrentColor}
onLongPress={(x) => console.log(x)}
containerStyle={s.containerStyle}
/>
<View style={s.btnContainer}>
<Pressable style={ButtonStyles.full}>
<Text style={s.btnText}>Fertig</Text>
</Pressable>
</View>
</BottomSheetModal>
)
});
In my function when I console.log currentColor its null but outside of the function it is setted , I dont check anything anymore I am very thankful for your help

Assuming your Colors component passes the color to your handleSetCurrentColor, you could try to set your currentColor like this
...
console.log(currentColor + 'current in func');
setCurrentColor(prevCurrentColor => prevCurrentColor === color ? null : color)
...

Related

How to use hooks as image's source in react native?

Im making this menu that when the user clicks at an option, it changes the background image, but i cant use the hook that i created as a parameter to the source of the image. Can someone find where im wrong and how to fix it?
Heres the part of my code referents to the menu and the hooks:
export function Home(){
let imagens = {
vovo: '../assets/vovoJuju.png',
mc: '../assets/mcJuju.png',
pato: '../assets/patoJuju.png',
}
const navigation = useNavigation<any>();
const [showBottomSheet, setShowBottomSheet] = React.useState(false);
const [param, setParam] = useState(1);
const [skin, setSkin] = useState('vovo')
const hide = () => {
setShowBottomSheet(false)
}
function handleAbout(){
navigation.navigate('About');
}
useEffect(() => {
if(param==1){
setSkin('vovo');
}
else if(param==2){
setSkin('mc');
}
else if(param==3){
setSkin('pato');
}
})
return(
<SafeAreaView style={styles.container}>
<TouchableOpacity onPress={handleAbout}>
<Counter />
</TouchableOpacity>
<TouchableOpacity onPress={() => {
setShowBottomSheet(true)
}}
>
<Image source={skin} style={styles.imgvj}/>
</TouchableOpacity>
<BottomSheet show={showBottomSheet} height={290} onOuterClick={hide}>
<Pressable onPress={hide} style={styles.bottomSheetContent}>
<Image source={barrinhaLoja} style={styles.barra}/>
</Pressable>
<View style={styles.conteudoLoja}>
<View style={styles.marginLeft48}>
<TouchableOpacity onPress={() => {
setParam(1);
}}>
<Image source={vovoJuju} style={styles.vovo}/>
<Text style={styles.legendasLoja}>Vovó Juju</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={() => {
setParam(2);
}}>
<Image source={mcJuju} style={styles.mc}/>
<Text style={styles.legendasLoja}>MC Juju</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={() => {
setParam(3);
}}>
<Image source={patoJuju} style={styles.pato}/>
<Text style={styles.legendasLoja}>Pato Juju</Text>
</TouchableOpacity>
</View>
</View>
</BottomSheet>
I created the "let imagens", "const param", "const skin" and the "useEffect trying" to make this function. I already tried using the source in different ways such as source={skin} and source={imagens[skin]} but it havent worked.
I'm not certain if this solves your problem, but here's how the first few lines of your component should look like without useEffect:
const imagens = {
vovo: '../assets/vovoJuju.png',
mc: '../assets/mcJuju.png',
pato: '../assets/patoJuju.png',
};
export function Home(){
const navigation = useNavigation<any>();
const [showBottomSheet, setShowBottomSheet] = React.useState(false);
const [param, setParam] = useState(1);
const hide = () => {
setShowBottomSheet(false)
}
function handleAbout(){
navigation.navigate('About');
}
let skin = 'vovo';
switch(param) {
case 1: skin = 'vovo'; break;
case 2: skin = 'mc'; break;
case 3: skin = 'pato'; break;
}
return /* the rest goes here */
}
To reference the actual image, you would use something like {imagens[skin]}.
I moved imagens outside of this function because it never changes, but it doesn't impact anything otherwise.

React native while adding one item id by onpress it adds all the item at once

can anyone tell me what can i do..i want to change the add button to remove button when one item added and again onpress remove ...add button will come..
function //
const [multipletest, setmultipleTest] = React.useState([]);
function addTest(crypto) {
setmultipleTest((state) => [...state, crypto.id]);}
map list //
{filterdData.map((crypto, index) => (
<View key={index.toString()}>
<TouchableOpacity onPress={() => addTest(crypto)}>
{console.log(crypto, "crypto")}
<Text> Add</Text>
</TouchableOpacity>
</View>
This logic might help
function Example() {
// default state
const [multipletest, setmultipleTest] = React.useState([]);
const add = (crypto) => {
let newData = [...multipletest];
newData.push(crypto.id);
setmultipleTest(newData);
}
const remove = (crypto) => {
let newData = [...multipletest];
newData = newData.filter((e) => e !== crypto.id);
setmultipleTest(newData);
}
// map list
return filterdData.map((crypto, index) => {
// check crypto id already exist or not
const exists = multipletest.includes(crypto.id);
return (
<View key={index.toString()}>
<TouchableOpacity
onPress={() => {
// handle onpress either add or remove as per condition
exists ? remove(crypto) : add(crypto);
}}
>
<Text>{exists ? "Remove" : "Add"}</Text>
</TouchableOpacity>
</View>
);
});
}

How to get ref x, y position in functional component in react-native?

I want to get the x, y position when the text cursor is focused on TextInput.
how to get ref position?
here is my code
const Code = () => {
const emailInput = useRef();
const scrollViewRef = useRef();
const [email, setEmail] = useState<string>('');
const scrollToEmail = () => {
// I want to scroll the y position of the scroll to the center where the TextInput's cursor is focused.
};
return (
<SafeAreaView style={{ flex: 1}}>
<ScrollView keyboardShouldPersistTaps="handled" ref ={scrollViewRef}>
<KeyboardAvoidingView enabled behavior={'padding'}>
<TextInput
ref={emailInput}
value={email}
returnKeyType="done"
onChangeText={(text) => setEmail(text)}
onFocus = {() => scrollToEmail()} <== function works here!
/>
</KeyboardAvoidingView>
</ScrollView>
</SafeAreaView>
);
};
export default Code;
i tried this
1.
const handler = findNodeHandle(emailInput.current);
console.log(
emailInput.measure(handler, (x, y, width, height) => {
console.log(y);
}),
); <== TypeError: emailInput.measure is not a function
const handler = findNodeHandle(emailInput.current);
console.log(emailInput.current.getBoundingClientRect()); <== TypeError: emailInput.current.getBoundingClientRect is not a function
there is no way get the ref's postition in a functional component?
You can use onLayout prop on the ScrollView to the the height, width, X and Y value.
If you want to use the ref, you have to set or console.log the X and Y value on a useLayoutEffect. This is because you need to wait for the component to be rendered and "drawn" before you get the information, otherwise you will get only 0

How to change state with useState hook using a variable

I have a FlatList with about 60 items.
Each item has a small button that is clicked to display more information inside the FlatList item.
<View style={styles.infoIcon} >
<TouchableOpacity onPress={() => { toggleInfo() }} >
<Ionicons name="ios-information-circle" size={40} color={"#0ca9dd"} />
</TouchableOpacity >
</View>
{showInfo ? <View><Text>{ itemData.item.info }</Text><View> : null }
The onPress toggle function is something like:
const toggleInfo = () => {
if (showInfo === true) {
setShowInfo(false);
} else {
setShowInfo(true);
}
};
Of course, since it's a FlatList, when I click the button all of the FlatList items show their hidden contents. But I only want the info for the clicked item to show, leaving all the others unchanged.
So, I changed the onPress to take an argument:
<TouchableOpacity onPress={() => { toggleInfo(itemData.item.id) }} >
...which is fine. But now I need to target the right state array (which is the same as the id but with an "z" tacked on the end to avoid any variable conflicts):
const toggleInfo =(id) => { // id might be "ABC"
const infoState = `${id}z`;
const infoStateSET = `set${speciesState}`; // therefore: setABCz
// Now I want to target the state "ABCz" and "setABCz" useState variables
if (infoState === true) {
infoStateSET(false);
} else {
infoStateSET(true);
}
};
Now, obviously there is no literal "infoStateSET" to change the state but I do want to use the variable to target the set state function.
Is this possible?
You can just set the id in showInfo state and then check if showInfo id is the same as the itemData.item.id.
basically you would have a state like this.
const [showInfo, setShowInfo] = useState(null);
Then you would set the state like so using your toggleInfo function:
const toggleInfo = (id) => {
if (showInfo === id) {
setShowInfo(id);
} else {
setShowInfo(null);
}
}
Then in your Flatlist item:
<View style={styles.infoIcon} >
<TouchableOpacity onPress={() => { toggleInfo(itemData.item.id) }} >
<Ionicons name="ios-information-circle" size={40} color={"#0ca9dd"} />
</TouchableOpacity >
</View>
{showInfo === itemData.item.id ? <View><Text>{ itemData.item.info }</Text><View> : null }

How to update useState into TextInput

I have a simple <TextInput> in React Native and i want to print some text when value change. Its working after second character entered, but not, when user press just one char.
I try using functions and even with onChange and take from e.target.value but allways are missing one character at "search" state.
import React, { useState } from 'react';
import { TextInput, View, Text } from 'react-native';
const App = () => {
const [search, setSearch] = useState('');
const [searching, setSearching] = useState(false);
return(
<View>
<TextInput
onChangeText={(value) => {
setSearch(value)
setSearching(search=='' ? false : true)
}}
value = { search }
/>
{
searching ?
(
<Text>Searching</Text>
) : (
<Text>No searching</Text>
)
}
</View>
);
}
export default App
I expect to show "Searching" when TextBox value are not empty.
useState or setState may be asynchronous, so the first time you call setSearch(value), the search state may not be updated yet.
onChangeText={(value) => {
setSearch(value)
setSearching(search == '' ? false : true) // "search" is still previous value
}}
Instead, you can directly use value instead for checking.
onChangeText={(value) => {
setSearch(value)
setSearching(value == '' ? false : true) // value is latest
}}
You need to compare the actual value of the TextInput
Using search=='' ? false : true will check the previous state and won't change
onChangeText={(value) => {
setSearch(value)
setSearching(search=='' ? false : true)
}}
This will check for the changed value.
onChangeText={(value) => {
setSearch(value)
setSearching(value == '' ? false : true) // use value
}}
You need to use value instead of search
Just change this
setSearching(search=='' ? false : true)
to
setSearching(value=='' ? false : true)
After help of both i resolved. This is the code if help to somebody. The idea are a TextInput with a len icon on the left, and when user start to write made the call to Firebase and show a loading icon on the right (spinner).
<Icon
name='search'
size={25}
color={PRIMARY_BACKGROUND_COLOR}
style={styles.searchIcon}
/>
<TextInput
underlineColorAndroid = 'transparent'
style = { styles.textBox }
onChangeText={(value) => { onChangeText(value) }}
value = { search }
placeholder = { i18n.t('Search') }
/>
{
searching ?
(
<TouchableOpacity style = { styles.visibilityBtn }>
<Animatable.View
ref={ref => (this.AnimationRef = ref)}
animation='rotate'
easing='linear'
iterationCount='infinite'
>
<Icon
name='spinner-3'
size={20}
color={PRIMARY_BACKGROUND_COLOR}
/>
</Animatable.View>
</TouchableOpacity>
) : (
<TouchableOpacity onPress={ clearSearch } style = { styles.visibilityBtn }>
<Icon
name='close'
size={20}
color={PRIMARY_BACKGROUND_COLOR}
/>
</TouchableOpacity>
)
}
And the function
const onChangeText = value => {
setSearch(value)
setSearching(value =='' ? false : true)
Helper.getCategoriesSearch(value, (categories) => {
setSearching(false)
//props.searchResults(categories); THIS DO NOT WORK RETURN DATA TO props :(
})
}
Thanks All