I have a list of questions. And on click of next or previous I'm changing the question. I have 4 or 5 answers as radio buttons. I' using this package Radio button npm. And now I'm trying to change the question using states. I need the radio button unselected on changing of question. All content changing easily expect radio button resetting. Here is my code:-
<ScrollView>
<RenderHtml
contentWidth={width}
source={{html:question}}
/>
<OptionsView options={options} selectedBtn={(e) =>updateAnswer(e.option)}/>
</ScrollView>
Functional component
const OptionsView=(props)=>{
return(
<RadioButtonRN
style={{marginHorizontal:5,marginTop:1,margin:5}}
deactiveColor={'gray'}
activeColor={'green'}
initial={0}
boxStyle={{height:50}}
data={props.options}
icon={
<Icon
name="check-circle"
size={25}
color="green"
/>
}/>
)}
I solved it using below code:-
import React, { useState } from "react";
import { View, StyleSheet, Button, Alert } from "react-native";
import RadioButtonRN from 'radio-buttons-react-native';
const App = () => {
const [show,setShow] = React.useState(true);
const data = [
{
label: 'data 1'
},
{
label: 'data 2'
}
];
React.useEffect(()=>{
if(!show) setShow(true)
},[show])
const resetHandler = () =>{
setShow(false)
}
return (
<View style={styles.container}>
{show &&
<RadioButtonRN
data={data}
selectedBtn={(e) => console.log(e)}
/>
}
<Button title='reset' onPress={resetHandler} />
</View>
);
}
const styles = StyleSheet.create({
container: {
paddingTop:100,
}
});
export default App;
Reference:- Radio Reset Button
If you are rendering your options base on the props that has been passed from parent component , U need to also include this hook in order to update your child component:
const OptionsView = (props.options) => {
const [options, setOptions] = useState(props.options);
useEffect(() => {
setOptions(props.options)
}, [props.options]
return (
<RadioButtonRN/>
)
}
Related
Actually i am working on multiple modal at once so i have to make a condition that if my modal with "xyz" ref is close then display a button.
react-native-modalize has onOpen and onClose props which will allow you to set some state to keep track of then open/closed status of each modal. You can then use that state to control the rendering of your buttons.
Example on Expo Snack.
import React, { useRef } from 'react';
import { View, Text, Button } from 'react-native';
import { Modalize } from 'react-native-modalize';
import RnGH from 'react-native-gesture-handler';
const { useState, useEffect } = React;
export default function App() {
const modalA = useRef(null);
const modalB = useRef(null);
const [modalAOpen, setModalAOpen] = useState(false);
const [modalBOpen, setModalBOpen] = useState(false);
return (
<>
<Button
onPress={() => {
if (modalAOpen) {
modalA.current?.close();
} else {
modalA.current?.open();
}
}}
title={`${modalAOpen ? 'Close' : 'Open'} Modal A`}
/>
<Button
onPress={() => {
if (modalBOpen) {
modalB.current?.close();
} else {
modalB.current?.open();
}
}}
title={`${modalBOpen ? 'Close' : 'Open'} Modal B`}
/>
<Modalize
ref={modalA}
onOpen={() => setModalAOpen(true)}
onClose={() => setModalAOpen(false)}>
<Text style={{ color: 'red' }}>Modal A</Text>
</Modalize>
<Modalize
ref={modalB}
onOpen={() => setModalBOpen(true)}
onClose={() => setModalBOpen(false)}>
<Text style={{ color: 'blue' }}>Modal B</Text>
</Modalize>
</>
);
}
You should make a custom component with a modal in it, so every modal has its own state - isOpen. Then in your custom modal component, you can show something or not, based on your isOpen property.
I need to build component from the picture. Basically it's regular radio button component, but when the user selects button named 'Other' text input should appear where user can enter custom value.
I already have built the group, I'm just not sure how handle the TextInput part.
What is the best way to structure the component like this?
import React from "react";
export const Radio = () => {
const [isOtherSelected, setOtherIsSelected] = React.useState(0);
const [value, setValue] = React.useState("0");
return (
<div>
<input
type="radio"
value="Other"
checked={isOtherSelected}
onChange={setOtherIsSelected(!isOtherSelected)}
/>
{isOtherSelected ? (
<input value={value} onChange={(e) => setValue(e.target.value)}></input>
) : (
""
)}
</div>
);
};
Just render text input if "other option" is checked. Control value of this input in state.
Simple minified example
import * as React from 'react';
import { View } from 'react-native';
import { RadioButton, Text ,TextInput} from 'react-native-paper';
const MyComponent = () => {
const [value, setValue] = React.useState('rent');
const [otherPayment,setOtherPayment] = React.useState('');
return (
<View style={{padding:15}}>
<RadioButton.Group onValueChange={newValue => setValue(newValue)} value={value}>
<View style={{flexDirection:'row',alignItems:"center"}}>
<Text>Rent</Text>
<RadioButton value="rent" />
</View>
<View style={{flexDirection:'row',alignItems:"center"}}>
<Text>Other</Text>
<RadioButton value="other" />
</View>
</RadioButton.Group>
{value === 'other' && <TextInput placeholder="Other Payment method" onChangeText={text=> setOtherPayment(text)}/>}
</View>
);
};
export default MyComponent;
Expo snack - https://snack.expo.dev/#emmbyiringiro/77f4e2
I'm trying to use composition component for making a menu in react native but I can't figure it why it doesn't work as expected.
I use [react native pop menu][1] to make the menu. Here what I'm trying to do :
Make a MenuContainer component with a children property
Make a MyMenuOptions component that will be nested inside the menu container as children.
import in my screen MyMenuOptions nested in MenuContainer
Issue: the menu container is working as expected but the MyMenuOptions is not showing on screen.
[1]: https://github.com/instea/react-native-popup-menu
MyMenuContainer component :
const MenuContainer = ({ nameMenu, children }) => {
const optionsStyles = {
optionsContainer: {
padding: 3,
width: 250,
},
};
return (
<Menu style={{ flexDirection: "row", marginRight: 10 }}>
<MenuTrigger
style={styles.triggerMenu}
text={nameMenu}
customStyles={{
TriggerTouchableComponent: TouchableWithoutFeedback,
}}
/>
<MenuOptions customStyles={optionsStyles}>{children}</MenuOptions>
</Menu>
);
};
MyMenuOptions Component :
import React from "react";
import { StyleSheet, Text } from "react-native";
import { MenuOption } from "react-native-popup-menu";
import MenuContainer from "./MenuContainer";
import { CheckBox } from "react-native-elements";
const MyMenuOptions = ({ textSubMenu, value, toggle }) => {
return (
<MenuContainer>
<MenuOption onSelect={toggle} style={styles.sousMenu}>
<CheckBox
center
title={textSubMenu}
checkedIcon="dot-circle-o"
uncheckedIcon="circle-o"
checked={value}
/>
</MenuOption>
</MenuContainer>
);
};
styles....
export default MyMenuOptions;
And in my final screen I import both component :
import MenuContainer from "../components/Menu/MenuContainer";
import MyMenuOptions from "../components/Menu/MenuCheck";
Some code ....
<View style={styles.menuOnglet}>
<MenuContainer nameMenu="Test menu">
<MyMenuOptions textSubMenu="My sub menu" value={true} />
</MenuContainer>
</View>
So as I said I can see the "Test menu" button show on my screen but i see nothing inside the menu when i click on it like there is no children.
Please, what am I missing here ?
why you surround MenuOption with MenuContainer in MyMenuOptions.js
const MyMenuOptions = ({ textSubMenu, value, toggle }) => {
return (
<MenuContainer> <!----------- you need to remove this -->
<MenuOption onSelect={toggle} style={styles.sousMenu}>
<CheckBox/>
</MenuOption>
</MenuContainer> <!---------- you need to remove this -->
);
};
you steps should be :
App.js file
it must be like this
import { MenuProvider } from 'react-native-popup-menu';
export const App = () => (
<MenuProvider>
<YourApp />
</MenuProvider>
);
MenuContainer.js file
const MenuContainer = ({ nameMenu, children }) => {
return (
<Menu >
<MenuTrigger/>
<MenuOptions>
{children}
</MenuOptions>
</Menu>
);
};
MyMenuOptions.js file
const MyMenuOptions = ({ textSubMenu, value, toggle }) => {
return (
<MenuOption onSelect={toggle} style={styles.sousMenu}>
.......
</MenuOption>
);
};
I am new to react native and have a problem figuring out how to navigate from one class to another one with passing parameters and would appreciate your help.
All I want to do is:
ClassA should have a checkbox with state handling and a flatlist containing CustomButton
Navigate from ClassA to TargetScreen by clicking CustomButton
Pass parameter "element" to TargetScreen
Show content of parameter passed in TargetScreen
The error message I get:
Error: Invalid hook call. Hooks can only be called inside of the body
of a function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See https://reactjs.org/warnings/invalid-hook-call-warning.html for tips about how to debug and
fix this problem.
ClassA:
import React, { Component, useState } from 'react';
import { useNavigation } from '#react-navigation/native';
import { CustomButton} from './CustomButton.js';
import { CheckBox, SafeAreaView, FlatList} from 'react-native';
class ClassA extends React.Component {
render() {
const [ASelected, setA] = useState(false);
const NavigateWithParams = () => {
navigation = useNavigation();
this.props.navigation.navigate('TargetScreen', { element: 'elementname' })
}
const renderItemCustom= ({ item }) => (
<CustomButton onPress={() => navigateWithParams()} />
);
}
return (
<CustomConst/>
<CheckBox value={ASelected}
onValueChange={{setA}} />
<SafeAreaView>
<FlatList
data={data}
renderItem={renderItemCustom}
keyExtractor={(item) => item.element}
/>
</SafeAreaView>
);
}
export default ClassA;
TargetScreen:
class TargetScreen extends React.Component {
render() {
const { navigation } = this.props;
return (
<Text> {JSON.stringify(navigation.getParam('element'))} </Text>
);
}
}
export default TargetScreen;
+++++++++++++++++++++++++
Update:
As of now the code looks like this:
class ClassA extends React.Component {
NavigateWithParams = (element) => {
this.props.navigation.navigate('TargetScreen', { element: 'elementname' })
}
renderItemCustom = ({ item }) => (
<CustomButton element={item.title} onPress={() => this.NavigateWithParams(item.element)} />
);
render() {
return (
<SafeAreaView>
<FlatList
data={data}
renderItem={this.renderItemCustom}
keyExtractor={(item) => item.id}
/>
</SafeAreaView>
);
}
}
export default ClassA;
And I am now getting this issue:
TypeError: Cannot read property 'navigate' of undefined
+++++++++++++++++++++++++
Update2
Routing:
function ClassA({ navigation }) {
return (
<ClassAScreen/>
);
function Target({ navigation }) {
return (
<TargetScreen/>
);
//navigation stacks
const SessionStack = createStackNavigator();
function SessionStackScreen({ navigation }) {
return (
<SessionStack.Navigator>
<SessionStack.Screen
name="ClassA"
component={ClassA}
options={{ tabBarLabel: 'ClassA!', headerShown: false }}
/>
<SessionStack.Screen
name="Target"
component={Target}
options={{ tabBarLabel: 'works!' }}
/>
</SessionStack.Navigator>
)
}
Logging gives me this:
renderItemCustom = ({ item }) => (
<CustomButton element={item.title} onPress={() => console.log(this.props)} />
);
+++++++++++++++++
Update:
Solution can be found here:
Navigation with parameters from custom element in Flatlist in React Native: Empty parameters
You cant use hooks inside a class component so remove the line which has the hook
and change like below
const NavigateWithParams = element => {
this.props.navigation.navigate('TargetScreen', { element: element })
}
const renderItemCustom= ({ item }) => (
<CustomButton onPress={() => this.navigateWithParams(item.element)} />
);
And parameter are passed using the route prop
class TargetScreen extends React.Component {
render() {
const { route} = this.props;
return (
<Text> {JSON.stringify(route.params.element)} </Text>
);
}
}
Also for the checkbox instead of using the useState hook, use this.state.
You can’t use Hooks inside a class component
https://reactjs.org/docs/hooks-faq.html#should-i-use-hooks-classes-or-a-mix-of-both
UPDATE:
Work variant, you can try here: https://snack.expo.io/#vasylnahuliak/stackoverflow-67862370
import 'react-native-gesture-handler';
import React from 'react';
import { Text, View, StyleSheet, Button, FlatList } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const DATA = [
{
id: 0,
title: 'first button',
element: 'something'
},
{
id: 1,
title: 'second button',
element: 'another something'
},
]
const HomeSceen = ({ route, navigation }) => {
return (
<View>
<Text>{JSON.stringify(route, null, 2)}</Text>
<Button
title="Navigate to ProfileScreen"
onPress={() => {
navigation.navigate('ProfileScreen');
}}
/>
</View>
);
};
const ProfileScreen = ({ route, navigation }) => {
const NavigateWithParams = (element) => {
navigation.navigate('HomeSceen', { element });
};
const renderItemCustom = ({ item }) => (
<Button title={item.title} onPress={() => NavigateWithParams(item.element)} />
);
return (
<View>
<Text>{JSON.stringify(route, null, 2)}</Text>
<FlatList
data={DATA}
renderItem={renderItemCustom}
keyExtractor={(item) => item.id}
/>
<Button
title="Navigate to HomeSceen"
color="tomato"
onPress={() => {
navigation.navigate('HomeSceen');
}}
/>
</View>
);
};
const SessionStack = createStackNavigator();
const App = () => {
return (
<NavigationContainer>
<SessionStack.Navigator>
<SessionStack.Screen name="HomeSceen" component={HomeSceen} />
<SessionStack.Screen name="ProfileScreen" component={ProfileScreen} />
</SessionStack.Navigator>
</NavigationContainer>
);
};
export default App;
I am trying to implement a react native image crop view and I am using :
https://github.com/hhunaid/react-native-image-crop-tools#readme
After a bit of fixing it works and apparenty there is automatically an output generated:
https://ibb.co/SBLvFGY
My question is, how can I get the value of the useRef Hook, since I want to store it in redux, it all is immensly confusing to me, the code :
import React, { useState, useRef } from 'react';
import { Button, StatusBar, StyleSheet, View, Image } from 'react-native';
import { CropView } from 'react-native-image-crop-tools';
import ImagePicker from 'react-native-image-picker';
import { connect } from 'react-redux';
import { changeNewIdeaImage } from '../../redux/actions/';
const TestImageCropper = () => {
const [uri, setUri] = useState();
const cropViewRef = useRef();
return (
<>
<StatusBar barStyle="dark-content" />
<View style={styles.container}>
<Button
title={'Pick Image'}
onPress={() => {
ImagePicker.launchImageLibrary(
{ noData: true },
(response) => {
setUri(response.uri);
}
);
}}
/>
{uri !== undefined && (
<CropView
sourceUrl={uri}
style={styles.cropView}
ref={cropViewRef}
onImageCrop={(res) => console.warn(res)}
keepAspectRatio
aspectRatio={{ width: 4, height: 4 }}
/>
)}
<Button
title={'Get Cropped View'}
onPress={() => {
cropViewRef.current.saveImage(true, 90);
}}
/>
</View>
</>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
cropView: {
flex: 1,
backgroundColor: 'red',
},
});
const mapStatetoProps = (state: any) => {};
export default TestImageCropper;
Now this is the most confusing part to me.Where does the saveImage view function even come from and how can I hook it up, so that I can save the Image uri in Redux, to display it?
<Button
title={'Get Cropped View'}
onPress={() => {
cropViewRef.current.saveImage(true, 90);
}}
/>
Thanks in advance!
The saveImage() seems like a method coming from CropView. Ref is simply storing - in your case - the rendered CropView element, so cropViewRef.current is basically the CropView in your TestImageCropper component, and you call it's built-in method with cropViewRef.current.saveImage(true, 90);
What not clear to me, is what is it that you want to store in redux? The value of the ref is the element itself.