I take photo to demonstrate, you may look at it:
My parent component is 1, grand child component place at 3, at 2 I can do some stuff because they is parent-child but I can't call function of 1 when I look from 3, any your interest, thanks!
you have to pass props from child to grandchild
here is an example (i use react native)
Parent.js
import React, { Component } from 'react';
import Child from './Child';
import { Button, Text, View } from 'react-native';
export default class Parent extends Component {
constructor(props) {
super(props);
this.state = {
result: 'original state'
}
}
stateUpdate(data) {
this.setState({result:data})
}
render() {
return (
<View>
<Text>parent state: {this.state.result}</Text>
<Button
onPress={() => this.stateUpdate('original state')}
title="original state"
color="darkgreen"
/>
<Child data={this.state.result} updateState={(data) => this.stateUpdate(data)} />
</View>
)
}
}
Child.js
import React, { Component } from 'react';
import GrandChild from './GrandChild';
import { Button, Text, View } from 'react-native';
export default class Child extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<Text style={{height:20}} />
<Text>child prop: {this.props.data}</Text>
<Button
onPress={() => this.props.updateState('Changed from Child')}
title="change parent state"
color="#841584"
/>
<GrandChild data={this.props.data} updateParent={(data) => this.props.updateState(data)} />
</View>
)
}
}
GrandChild.js
import React, { Component } from 'react';
import { Button, Text, View } from 'react-native';
export default class GrandChild extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<Text style={{height:20}} />
<Text>GrandChild prop: {this.props.data}</Text>
<Button
onPress={() => this.props.updateParent('change from GrandChild')}
title="change parent state"
color="darkblue"
/>
</View>
)
}
}
here is a snack
https://snack.expo.io/GsuAf65kK
or use context api.
hope it help.
Related
I'm currently developing an application using React Native.
This trial app has a parent function component and a child class component.
I want to send a state value from the parent to the child using props.
even though I use setState(), the state value doesn't change...
how can I resolve my problem?
Here is the code:
Parent
import React, { useState } from "react";
import { View } from "react-native";
import Child from "../components/Child";
export default function Parent() {
const [texts, setTexts] = useState("AAA");
return (
<View>
<Child texts={texts} />
</View>
);
}
Child
import React from "react";
import { Button } from "react-native";
class Child extends React.Component {
constructor(props) {
super(props);
this.state = { texts: props.texts };
}
handleChange = () => {
const { texts } = this.props;
this.setState({ texts: "BBB" });
console.log("handleChange");
console.log(texts);
};
render() {
const { texts } = this.props;
console.log("render");
console.log(texts);
return (
<Button
title="ADD"
onPress={() => {
this.handleChange();
}}
/>
);
}
}
export default Child;
node : 12.18.3
react native : 4.10.1
expo : 3.22.3
You actually need to pass a callback function to the Child which will then set the state on the parent.
Parent
import React, { useState } from "react";
import { View } from "react-native";
import Child from "../components/Child";
export default function Parent() {
const [texts, setTexts] = useState("AAA");
return (
<View>
<Child setText={setTexts} />
</View>
);
}
Child
import React from "react";
import { Button } from "react-native";
class Child extends React.Component {
render() {
return (
<Button
title="ADD"
onPress={() => {
this.props.setText(dataYouWantToAdd);
}}
/>
);
}
}
export default Child;
You should pass a callback function to let the parent handle the change how it needs to. Just pass the data back to the parent in the callback. Try this if you still got error do let me know
parent
import React, { useState } from "react";
import { View } from "react-native";
import Child from "../components/Child";
export default function Parent() {
const [texts, setTexts] = useState("AAA");
const handleText = (val)=>{
setTexts(val)
}
return (
<View>
<Child texts={texts} handleChange={(texts)=>handleText(texts)}/>
</View>
);
}
child
import React from "react";
import { Button } from "react-native";
class Child extends React.Component {
render() {
return (
<Button
title="ADD"
onPress={() => {
this.props.handleChange(this.state.texts);
}}
/>
);
}
}
export default Child;
I am trying to send value of TextInput to another Class Function in console.log. My approach is when the button is pressed the value FromStr in TextInput will got passed into another class function. Here's my code
import React, { Component } from "react";
import { StyleSheet, Text, View, TextInput, Button } from "react-native";
import receiveMessage from "./receiveMessage"
export default class WeatherProject extends Component{
constructor (props) {
super(props);
this.state={
From:'',
FromStr:'',
}
}
changeText=(From)=>{
this.setState({From})
}
changeText1=(To)=>{
this.setState({To})
}
onPress = ()=>{
this.setState({FromStr: this.state.From})
receiveMessage.receiveMessage();
}
render(){
return (
<View>
<View style={styles.inputFields}>
<TextInput placeholder="From" id="from" style={styles.fromField} onChangeText={this.changeText} />
<View style={styles.buttonStyle}>
<Button
title={"Go Back"}
color="#f194ff"
onPress={this.onPress}
></Button>
</View>
</View>
</View>
);
}
}
receiveMessage.js
import React, { Component } from "react";
export default class receiveMessage extends Component {
static receiveMessage=()=>{
console.log(this.state.FromStr)
}
}
React does not allow to pass the data between react components in this way.
Following is way to pass the data between components in React. To get more insights please follow
import React, { Component } from 'react';
class WeatherProject extends Component {
render() {
const messageToPassed = 'Hello';
return (
<div>
<ReceiveMessage message={messageToPassed} />
</div>
);
}
}
const ReceiveMessage = props => <h1>{props.message}</h1>;
export default App;
here we pass the value from sidemenu component by raising an event
App.js
class App extends React.Component {
handleSubmit = (e, data) => console.log(`my data from props`, data);
render() {
return (
<Sidemenu
onSubmit={(e, data)=>this.handleSubmit(e, data)} />
);
}
}
SideMenu.js
const Sidemenu = props => {
const { onSubmit} = props;
return (
<button onClick={(e, type)=>this.onSubmit(e, 'mydata')} />
);
}
To start i am sorry i am a new on native react
I have a project with react navigation who show this component.
import React, { Component } from 'react';
import {FlatList,StyleSheet,View,TouchableHighlight,Text} from 'react-native'
import {
Container,
Button,
ListItem,
Left,
Right,
Icon,
Body
} from 'native-base';
import Customer from '../Customer';
import Search from '../../../components/Search'
export default class SearchCustomer extends Component {
constructor(props) {
super(props);
this.state = {
customerList:[]
}
}
render() {
return (
<Customer>
<Search
setCustomerList = {(customerList) => {this.setState({customerList})}}
/>
<FlatList
data={this.state.customerList}
keyExtractor={item => item.id}
renderItem={({ item, index}) => (
<ListItem onPress={(item) => this.props.callback()}>
<Left style={styles.left}>
<Text>{item.firstname} {item.lastname}</Text>
<Text style={styles.subtitle}>{item.email}</Text>
</Left>
<Right>
<Icon name='arrow-forward' />
</Right>
</ListItem>
)}/>
</Customer>
)
}
}
This component call his parent that here below
import React, { Component } from 'react';
import {
Container,
Button,
Text,
} from 'native-base';
import Order from '../Order';
export default class Customer extends Component {
constructor(props) {
super(props);
this.state = {
}
}
render() {
return (
<Order>
{this.props.children}
</Order>
)
}
}
I want to know how can i send data from the child to his parent with this configuration.
Currently i am trying to catch this.props.callback() in the parent but i can't use this callback={() => {console.log('Ok')}}
I have this error
Someone have a solution ?
Using some of your class you can define a method in your parent class then pass the function as props to child
export default class Customer extends Component {
constructor(props) {
super(props);
this.state = {
}
}
callback = (data) => { console.log(data) }
render() {
return (
<Order callback={this.callback}>
{this.props.children}
</Order>
)
}
}
Then from child you can provide the data in the callback for parent.
export default class Order extends Component {
constructor(props) {
super(props);
this.state = {
}
}
render() {
return (
<TouchableOpacity onPress={() => this.props.callback('hi')}>
<Text>Click Me!</Text>
</TouchableOpacity >
)
}
}
read this for more good understanding : https://reactjs.org/tutorial/tutorial.html#passing-data-through-props
I would like to close the child component from the child when user click on the close button in child component. Tried to it by passing the state from the child back to the parent but it's not working. What have i done wrong here?
Parent
class Home extends Component {
constructor() {
this.state = {
visible: true
}
{
closeComponent = () => {
this.setState({
visible: false
});
}
render() {
return (
<Container>
{
this.state.visible &&
<Child closeComponent={this.closeComponent} />
}
</Container>
)
}
}
Child
import React from 'react';
import { Text, Image } from 'react-native';
import { View, Button } from 'native-base';
import styles from './ChildStyles.js';
export const Child = ({ closeComponent }) => {
return (
<View style={styles.Container}>
<Button style={styles.Btn} onClick={() => closeComponent}>
<Text style={styles.BtnText}>Close</Text>
</Button>
</View>
);
};
export default Child;
The syntax for arrow function in child is incorrect. Also native-base Button doesn't have an onClick but an onPress handler. It should be
<Button style={styles.Btn} onPress={() => closeComponent()}>
<Text style={styles.BtnText}>Close</Text>
</Button>
When i try to use DatePickerIOS with react native nothing happen in my phone ...
my code :
import React, { Component } from 'react';
import {Text, View, DatePickerIOS} from 'react-native';
export default class DatePicker extends Component {
constructor(props) {
super(props);
this.state = {
today: new Date(),
}
}
render() {
return (
<View>
<DatePickerIOS date={this.state.today} mode="time" onDateChange={(value) => this.setState({today: value})}/>
</View>
);
}
}
SomeOn know why ?
If you want to print selected time in the UI add the following to the render
render() {
return (
<View>
<DatePickerIOS
date={this.state.today}
mode="time"
onDateChange={(value) => this.setState({today: value})}
/>
<Text>{this.state.today.toTimeString()}</Text>
</View>
);
}