undefined is not a function (evaluating 'this.props.navigation.state.params - react-native

I have a parent and child, I am using navigator to route between them, I have some state in the child component and I want to pass the state value in that component to the parent without routing the parent.
so far I have the code as follow:
on my parent:
<TouchableOpacity
onPress={() =>
this.props.navigation.navigate('Riddles', {
onChangeCount: this.onChangeCount.bind(this)
})}
>
as you can see on my parent (which is the home screen) I have butten that onPress navigate to Riddles screen (which is my child component)
on the child component I setup as follow:
nextQuestion() {
this.setState({
userAnswer: '',
count: this.state.count + 1,
diamonds: this.state.diamonds + 5
})
const { navigate } = this.props.navigation
this.props.navigation.state.params.onChangeCount(1)
this.refs.modalCorrect.close()
this.saveData()
}
and render it (on child - riddles screen ):
return (
<TouchableOpacity
style={styles.modalButtonAnswer}
onPress={() => this.nextQuestion()}
>
as much as I understod, the line " this.props.navigation.state.params.onChangeCount(1)" send the value "1" to my parent screen and in the parend screen I need to bind this (https://github.com/react-navigation/react-navigation/issues/1416)
, but it doesn't work for me, please help....

Related

React Native -Undefined param while coming back to previews screen

I have a root screen called selectlanguage once user select his language I'm passing that selected language as params to the Home screen, and then to "Home" children. but once I hit back button from that child screen to the Home that param turns to undefined that why when I want to open that child screen again it cause some issues.
Root screen selectedLanguage:
<View style={{ marginTop: 40 }}>
<Button
handleClick={() =>
navigation.navigate('Home', { lan: userLanData.value })
}
title={'NEXT'}
{...}
/>
Home screen:
const lan = route.params?.lan;
// and below i'm passing above param as props to Task screen
<Tasks
lanParam={lan}
{...}
/>
Task screen:
//Again passing it to another Child screen
<TouchableOpacity
onPress={() =>
navigation.navigate('byWords', {
id: item.id,
currentLevelName,
index,
lanParam, <-----
})
}>
{...}
</TouchableOpacity>
Task Child screen:
const lanParam = route?.params?.lanParam;
const colRef = collection(
db,
`${lanParam && lanParam}/${currLevelParam}/tasks/${id}/byWords/`
);
And from this point I had an idea to try send this Param back to home screen while coming back like this:
<Header
{...}
goBack={() =>
navigation.navigate('Home', { index, currLevelParam, lanParam })
}
/>
And now Home screen should look like this and I'm receiving that value back again:
Home screen:
const lan = route.params?.lan;
const lanParam = route.params?.lanParam;
// and below i'm passing above param as props to Task screen
<Tasks
lanParam={lan}
{...}
/>
But the problem is that, how could I use that value again since we have no access to the root screen again ?
it was easy to fix!!
I just modified lanParams to lan to keep same as Original param and update Home param again while coming back

pass the status from the parent screen to the children screen

hi everyone i am new to react-native and i have a problem in passing the status from the parent component (HomePage.js) to the daughter component (SecondPage.js). On the parent screen (HomePage)
instead of just having the button, I also have the result of the daughter's status. i.e. on the Homepage I have:
"result is: ooo" and below I have the button. If I click on the button, the SecondPage screen appears with the result "result is:" without passing the value of the state of the parent component "ooo".
in HomePage.js
export default class HomePage extends Component {
static navigation={}
constructor(){
super();
this.state = {alreadyLaunched: null,sid:"ooo"};
}
render(){
return (
<View style={styles.container}>
<SecondPage stato={this.state.sid} />
<Button
onPress={ () => this.props.navigation.navigate('SecondPage')}
title="DETAILE" color="orange"/>
</View>
);
}
}
And in SecondPage.js
export default class SecondPage extends Component {
render(){
return (
<View >
<Text>result is: {this.props.stato}</Text>
</View>
)
}
}
I want to have in the parent screen (HomePage), a button that takes me to the child screen that shows me the result "result is:ooo". how can I solve my problem? because in the parent screen (HomePage) I have the result of the child screen (SeconPage )?
you have two mode of using second page. the first mode is using component in your home page and it's correct.but in the navigation mode you should pass the parameter in this way =>
<Button onPress={ () => this.props.navigation.navigate('SecondPage', {stato: this.state.sid})} title="DETAILE" color="orange"/>
and in the second page =>
result is: {this.props.stato ? this.props.stato : this.props.navigation.state.params.stato}
note:
if you use new version of react navigation instead of (this.props.navigation.state.params.stato) use route.params.stato

react native How to get child component const value to parent screen component

I have one text input in my child component and I want to get the text input data to my parent screen. I want to pass the data to one component to another component.
You have 2 components parent and child suppose , then it would be like
In render of Parent , basically you are passing a callback function to child
textChange = (value) => {
this.setState({newText:value});
}
render(){
return(
<Child onTextInput={this.textChange} />
)
}
and in child's render:
render(){
return(
<TextInput onChangeText={e => this.props.onTextInput(e)}
)
}
Hope it helps.

React - native StackNavigator refresh previous component after hitting back button

I'm stuck for weeks on this problem that I can't solve. I have been through a lot of different solution and none of them is working..
Let-s say I have component A and component B
Component A : contains a flatlist, when click on one item leads me to component B.
Component B: contains details of component A items, when clicking on a button update data, data that component A is using in state current, which make the clicked items turn to orange. I would like when hitting back button to update those data in component A and actually have the clicked items in orange, right now nothing is happening..
Component A :
async interventionList(){
const planningList = await getInterventionList(this.state.userToken, '2019-02-27', '2019-02-27');
this.setState({list: planningList});
}
renderItem = ({ item }) => (
<View>
<TouchableHighlight onPress={
() => this.props.navigation.navigate('InterventionStart', { getIntervention: () => this.interventionsList() })}>
<View style={[styles.block, this.state.current !== null && this.state.current.remoteInterventionId === item.num ? styles.began : styles.notbegan]}>
<Text> {SomeData} <Text>
</View>
</View>
</TouchableHighlight>
</View>
)
Component B :
componentWillUnmount() {
this.props.navigation.state.params.getIntervention();
}
But nothing happens. I tried to console log, to see if those functions where called after clickin on back button and they are... So I don't understand what I am doing wrong or is it not the way to do this at all ?
You can use willFocus method of react-navigation
in your componentDidMount or in your constructor
this.willFocus = this.props.navigation.addListener('willFocus', () => {
this.interventionList();
});
It will call your interventionList method whenever your component is about to be focused. Make sure you remove the listener on your componentWillUnmount
this.willFocus.remove();
For reference
https://reactnavigation.org/docs/en/navigation-events.html

Methods inside of functional components

I'm experiencing a strange issue where the onPress function of a functional child component is triggered whenever the component is rendered.
Relevant parent code which renders the child component from a list of dates. I was also having issues with array.map if the component was a class component, but that's a separate issue.
return list_items.map(data =>
<ChildComponent
key={data.day}
props={data}
/>);
And the child component:
const ChildComponent = ({ props }) => {
let date = props.date;
const someFunction = () => {
console.log(date)
}
return (
<Text><Icon name="angle-right" onPress={someFunction()}/></Text>
)
And what I get from the console upon rendering the relevant scene:
2018-11-11
2018-11-12
2018-11-13
2018-11-14
2018-11-15
2018-11-16
Pressing the icon does nothing, yet it seems to run the function as if it was a lifecycle component. I've also moved the function into the parent component and passed it to the child as recommended per Guruparan Giritharan, and it still executes on render.
return list_items.map(data =>
<ChildComponent
key={data.day}
props={data}
someFunction={this.someFunction} // function now within parent component
/>);
And the updated child:
const ChildComponent = ({ props, someFunction }) => {
return (
<Text>
<Icon name="angle-right" onPress={someFunction(props.date)}/>
</Text>
)
}
Change to
<Text><Icon name="angle-right" onPress={someFunction}/></Text>
You are calling the function there itself instead of passing the reference. So the function is called inside each render instead of onPress.