How to reference button in card component in React Native? - javascript

I'm a newbie to React/React Native, so please go easy on me. I've been stuck on this for a little while now so could use some help. Using functional React Native by the way.
How do I reference buttons that are in a card component from another screen? Using props in the card to display the toilet object's variables isn't a problem, but the buttons that are rendered through the card I can't work out how to reference them from the component with the map. Using navigation within the card doesn't work.
Screen that I want to reference the button in
{toilets.map((item, index) => {
return (
<ToiletCard
key={index}
title ={item.title}
address={item.address}
ratings={item.rating}
reviews={item.reviews}
onPress={() => {navigation.navigate("ReviewViewAndCreate", item)}}
/* I want to reference the review button using this onPress, but right now it isn't
referencing either button /*
/>
)
})}
Card component that contains the buttons
export default ToiletCard = (props) => {
return (
<View style = {styles.textContent}>
<View style = {{padding: 15}}>
<Text numberOfLine={1} style = {styles.listTitle}>{props.title}</Text>
<Text numberOfLine={1} style = {styles.listAddress}>{props.address}</Text>
<Text><StarRating ratings={props.ratings}/>{props.ratings}</Text>
<TouchableOpacity
style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>Directions</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.appButtonContainerTwo}>
<Text style={styles.appButtonText}>Reviews</Text>
</TouchableOpacity>
</View>
<View style={styles.hairline}/>
</View>
)
}
Would appreciate any help.
Thanks!

Do these changes:
{toilets.map((item, index) => {
return (
<ToiletCard
key={index}
title ={item.title}
address={item.address}
ratings={item.rating}
reviews={item.reviews}
item={item}
navigation={navigation}
/* pass item as prop to this component /*
/>
)
})}
ToiletCard component:
export default ToiletCard = (props) => {
return (
<View style = {styles.textContent}>
<View style = {{padding: 15}}>
<Text numberOfLine={1} style = {styles.listTitle}>{props.title}</Text>
<Text numberOfLine={1} style = {styles.listAddress}>{props.address}</Text>
<Text><StarRating ratings={props.ratings}/>{props.ratings}</Text>
<TouchableOpacity
style={styles.appButtonContainer}>
<Text style={styles.appButtonText}>Directions</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {props.navigation.navigate("ReviewViewAndCreate", props.item)}}
style={styles.appButtonContainerTwo}>
<Text style={styles.appButtonText}>Reviews</Text>
</TouchableOpacity>
</View>
<View style={styles.hairline}/>
</View>
)
}

Related

How to pass up nested state and avoid useCallback in react native

I have a parent and nest child component hierarchy of QuestionsAndAnswersScreen -> QuestionInput -> QuestionSelector -> AnswerSelector. I need to pass the question and answer object back up to the QuestionAndAnswerScreen in order to show it on the view. However I cannot find a way without going into deep nested callbacks.
Here is my code for the QuestionAnswerScreen and AnswerSelector:
function QuestionsAndAnswers() {
const {shell, body} = styles;
return (
<View style={shell}>
<SignUpHeader title="Add your answers" page={5}/>
<View style={body}>
{qAndA[1] ? <Answer question={qAndA[1].question} answer={qAndA[1].answer}/> : <QuestionInput />}
{qAndA[2] ? <Answer question={qAndA[2].question} answer={qAndA[2].answer}/> : <QuestionInput />}
{qAndA[3] ? <Answer question={qAndA[3].question} answer={qAndA[3].answer}/> : <QuestionInput />}
</View>
<SignUpFooter
title={`Questions\n& Answers`}
buttonTitle={"Done"}
disabled={false}
route="QuestionsAndAnswers"
/>
</View>
);
}
function AnswerInput(props: AnswerInputProps) {
const {question, visible, answerModalVisible} = props;
const {pickAnAnswer, doneButton, answerTextInput, questionStyle, shell, buttonText} = styles;
const [modalVisible, setModalVisible] = useState(visible)
const [answer, setAnswer] = useState('');
const navigation = useNavigation();
useEffect(() => {
setModalVisible(visible)
}, [visible])
function answerQuestion() {
setModalVisible(false);
navigation.navigate('QuestionsAndAnswers');
}
return (
<View>
<Modal style={shell}
isVisible={modalVisible}
onBackdropPress={() => {
setModalVisible(false);
answerModalVisible(false);
}}
>
<View>
<Text style={pickAnAnswer}>Add answer</Text>
</View>
<View>
<Text style={questionStyle}>{question}</Text>
</View>
<View>
<TextInput
style={answerTextInput}
placeholder="Add your answer here..."
placeholderTextColor="#878787"
onChangeText={(text: string) => setAnswer(text)}
/>
<View style={{alignItems: 'flex-end', marginTop: 44}}>
<TouchableOpacity style={doneButton} onPress={() => answerQuestion()}>
<Text style={buttonText}>
Done
</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</View>
);
}
As you can see I get my Question and Answer in the AnswerInput but then need to navigate back to the main screen in order to display them. Any help would be great thanks :)

How to dynamically add or remove a Text Input in React Native

How can I add a text input in React Native with the click of a button? For example, I would press the "+" button and it would add a text input at the bottom of the View.
here is the code i found in another page but when i click on the plus nothing happen
var textInput = []
let addTextInput = (key) => {
textInput.push(<TextInput key={key} style={{color:'red',borderColor:'red'}}/>);
{ textInput }
}
let orgServiceandWorkHours = (
<View>
<Button title='+' onPress={() =>
addTextInput(textInput.length)} />
{textInput.map((value, index) => {
return value
})}
</View>
)
Heres a full example (https://snack.expo.dev/#heytony01/mature-carrot) and the code below.
export default function App() {
const [numTextInputs,setNumTextInputs] = React.useState(0);
return (
<View style={styles.parent}>
{/* Button */}
<TouchableOpacity onPress={()=>setNumTextInputs(val=>val+1)} style={styles.buttton}>
<Text style={styles.text}> Add TextInput </Text>
</TouchableOpacity>
<ScrollView style={{flex:1}} >
{[...Array(numTextInputs).keys()].map(key=>{
return <TextInput key={key} placeholder="Here Man" style={{width:200,height:100,borderColor:"blue",margin:10,borderWidth:1}}/>
})}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
parent:{flex:1,justifyContent:"center",alignItems:"center"},
textInput:{width:"80%",height:"5%",backgroundColor:"lightgray",margin:20,borderRadius:10,textAlign:"center"},
buttton:{width:"80%",height:"12%",backgroundColor:"lightblue",borderRadius:10,
justifyContent:"center",alignItems:"center"
},
text:{fontSize:30,fontFamily:"bold",color:"black"},
})

Warning: Cannot update a component from inside the function body of a different component. in TouchableOpacity

I got this error
Warning: Cannot update a component from inside the function body of a different component.
How to fix this ?
When I remove touchable opacity, it's not showing anymore
<View style={styles.SaD}>
<TouchableOpacity onPress={(e) = props.locationSetState(1)}> // here
<Text style={styles.text1}>Choose your starting point</Text>
</TouchableOpacity>
<TouchableOpacity onPress={(e) = props.locationSetState(2)}>
<Text style={styles.text1}>Choose destination</Text>
</TouchableOpacity>
</View>
details are not sufficient to understand your problem but according to what I understand from your code try using react hooks and try this
function App() {
const [state,setState]=React.useState(null);
console.log(state);
return (
<View style={styles.SaD}>
<TouchableOpacity onPress={(e) => setState(1)}>
<Text style={styles.text1}>Choose destination</Text>
</TouchableOpacity>
<TouchableOpacity onPress={(e) => setState(2)}>
<Text style={styles.text1}>Choose destination</Text>
</TouchableOpacity>
</View>
);
}

React Native Touchable Opacity

I have this code, in which TouchableOpacity is not working and i don't know why:
const Box = (props) => {
return (
<View>
<TouchableOpacity onPress={() => {props.callBackProp(); props.budCallBackProp(props.name)}}>
<View style={styles.inputBox}>
<Text style={styles.testText}>{props.name}</Text>
</View>
</TouchableOpacity>
</View>
);
}
What is wrong here?
Edit:
At first, i click on this blue button with "budynek" text inside it, which opens something that looks like a list. Then after i click on some option i want it to dissapear, which is what these callbacks are for. I wrapped each option in this TouchableOpacity component but nothing happens after i click it - there is no effect of a click. A view which holds these "Box" component is absolutely positioned. Here is rest of the code:
return (
<View style={styles.rozwijanaPoz}>
<Pusty/>
<Box name={"budynek 1"} callBackProp={props.callBack} budCallBackProp={props.budCallBack}/>
<Box name={"budynek 2"} callBackProp={props.callBack} budCallBackProp={props.budCallBack}/>
<Box name={"budynek 3"} callBackProp={props.callBack} budCallBackProp={props.budCallBack}/>
</View>
);
}
const styles = StyleSheet.create({
rozwijanaPoz: {
position: "absolute",
left: 60,
},
});
And the main container:
<TouchableOpacity onPress={() => setIsVisible(true)}>
<View style={styles.budynekContainer}>
<Text style={styles.budynekTekst}>{budynekText}</Text>
{isVisible ?
<Rozwijana callBack={visibleCallBack} budCallBack={budynekCallBack}/>
: null}
</View>
</TouchableOpacity>

React Native : How to call child refs from the parent's event funtion?

Have parent tag as <TouchableWithoutFeedback> and child as <Image>, trying to change the image source from the parent onPress function, but getting error. how can I archive this using refs? or any other way to resolve it?
React-native version : 0.56
Error :
Cannot read property 'favIcon' of undefined
Sample Code :
const fav = require('../../images/favorite.png');
const nonfav = require('../../images/not_favorite.png');
updateFavorite = (id) => {
this.props.refs.favIcon.source(fav);
}
render(){
return (
<View style={styles.container}>
<TouchableWithoutFeedback onPress={ this.updateFavorite.bind(this, 1) }>
<View style={ styles.imageView }>
<Image refs="favIcon" source={ nonfav } />
</View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={ this.updateFavorite.bind(this, 2) }>
<View style={ styles.imageView }>
<Image refs="favIcon" source={ nonfav } />
</View>
</TouchableWithoutFeedback>
</View>
)
}
Note : change only the child image of onPressed, not all images.
try it using nativeProps, like
import resolveAssetSource from 'resolveAssetSource';
this.refs['favIcon'].setNativeProps({
src: [resolveAssetSource(fav)]
});
refer this for more.
It might not work with react-native 0.50+ versions but according to this comment it should work with 0.57.1
Updating properties of elements in React is best done by calling setState method. Try the following
updateFavorite = (event) => {
event.target.setAttribute('src', fav)
}
render(){
return (
<View style={styles.container}>
<TouchableWithoutFeedback>
<View style={ styles.imageView }>
<img ref={ref => this.favIcon = ref} src={nonFav} onPress={ this.updateFavorite }/>
</View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback>
<View style={ styles.imageView }>
<img ref={ref => this.favIcon = ref} src={nonFav} onPress={ this.updateFavorite } />
</View>
</TouchableWithoutFeedback>
</View>
)
}

Categories

Resources