Skip to content

Commit 1eca0d8

Browse files
committed
passing date from child to parent
1 parent dff1f06 commit 1eca0d8

4 files changed

+380
-318
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,32 @@
1-
## Passing simple Props from Parent to Child — where the prop is not a function
2-
3-
Inside the parent component, just do ``<ChildComponent propName={this.props.propName} />`` and then inside the child component just do ``{this.props.propName}``
4-
5-
[Implemented example](https://github.com/rohan-paul/React-snippets/blob/master/Wrapper-Component-Print-Users-Followers-With-Webpack-Setup/src/App.js)
6-
7-
```js
8-
class App extends React.Component {
9-
render () {
10-
return (
11-
<div>
12-
<Profile
13-
name={this.props.profileData.name}
14-
imgURL={this.props.profileData.imgURL}/>
15-
<Followers
16-
followerList={this.props.profileData.followerList} />
17-
</div>
18-
);
19-
}
20-
};
1+
## Child to Parent — Use a callback and states
212

22-
class Profile extends React.Component {
23-
render () {
24-
return (
25-
<div>
26-
<h3>{this.props.name}</h3>
27-
<img src={this.props.imgURL} />
28-
</div>
29-
);
30-
}
31-
};
3+
We need a way for the child component to tell the parent component to update without breaking one-way data flow. Since we are using local state, we need a way for the child component to tell the parent component to call setState. One way to solve this is to create a function in the parent component and add it as a property on the object passed to our render prop. Then whenever the child component needs to update state, it calls this function.
324

33-
class Followers extends React.Component {
34-
render () {
35-
var followers = this.props.followerList.map(function(follower, index){
36-
return (<li key={index}>{follower}</li>);
37-
});
38-
39-
return (
40-
<div>
41-
<h5>My followers:</h5>
42-
<ul>
43-
{followers}
44-
</ul>
45-
</div>
46-
);
47-
}
48-
};
49-
```
50-
51-
## Child to Parent — Use a callback and states
5+
This function then executes in the parent context and calls setState. Once setState is run, if any state value has changed, those new values propagate down into our render prop and the child component now receives the new value.
526

537
### For passing from child to parent - pass one callback function from parent to child and then use this passed-down function in the child to send something back to parent.
548

559
Same tutorial - https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17
5610

5711
### A> Define a callback in my parent which takes the data I need in as a parameter.
5812

59-
### B> Pass that callback as a prop to the child (just like the way in Point no-1 above) - this is it will be a regular prop passing from parent to child.
13+
### B> Pass that callback as a prop to the child.
6014

6115
### C> Call the callback using this.props.[callback] in the child (insert your own name where it says [callback] of course), and pass in the data as the argument.
6216

63-
6417
Here’s what that might look like if I had data in **ToDoItem** (the Child Component) that I need to access in **ToDoList**(The parent Component) : And the data that **ToDoList** will receive from the child **ToDoItem** is given a variable name **listInfo** for example.
6518

6619
```js
6720
// Parent component
68-
class ToDoList extends React.Component {
21+
class ParentToDoList extends React.Component {
6922

7023
myCallback = (dataFromChild) => {
7124
// [...we will use the dataFromChild here...]
7225
},
7326
render() {
7427
return (
7528
<div>
76-
<ToDoItem callbackFromParent={this.myCallback}/>
29+
<ChildToDoItem callbackFromParent={this.myCallback}/>
7730
</div>
7831
);
7932
}
@@ -82,7 +35,7 @@ class ToDoList extends React.Component {
8235
// Now from within ToDoItem (The Child Component) we can pass something to callbackFromParent (the prop that was given the value or assigned the value of the CB function that was defined in the parent ) :
8336

8437
// Child component
85-
class ToDoItem extends React.Component{
38+
class ChildToDoItem extends React.Component {
8639
someFn = () => {
8740
// [...somewhere in here I define a variable listInfo which I think will be useful as data in my ToDoList component...]
8841
this.props.callbackFromParent(listInfo);
@@ -94,12 +47,45 @@ class ToDoItem extends React.Component{
9447

9548
```
9649

50+
ToDoList will now be able to use listInfo within it’s myCallback function!
51+
52+
### But what if I want to use 'listInfo' in a different function within ToDoList, not just in myCallback so I get 'listInfo' as a regular variable in the parent component ? With the above implementation, I would only have access as a parameter passed into that one specific method.
53+
54+
#### Easy: set this parameter as a state within ToDoList. You can almost think of it as creating a variable within the scope of ToDoList that all the methods within that component can access. In that case my code defining ToDoList might look something like:
55+
56+
```js
57+
class ToDoList extends React.Component {
58+
constructor(props) {
59+
super(props);
60+
this.state = {
61+
listDataFromChild: null
62+
};
63+
},
64+
myCallback = (dataFromChild) => {
65+
this.setState({ listDataFromChild: dataFromChild });
66+
},
67+
otherFn = () => {
68+
// ..within this other function now I still have access to this.state.listDataFromChild...
69+
}
70+
render() {
71+
return (
72+
<div>
73+
<ToDoItem callbackFromParent={this.myCallback}/>
74+
[...now here I can pass this.state.listDataFromChild as a prop to any other child component...]
75+
76+
</div>
77+
);
78+
}
79+
});
80+
81+
```
9782

9883
## Another Implementation of the above concept in below file -
9984

10085
[https://github.com/rohan-paul/Fetch-Github-Profile/blob/master/simple-version-without-using-redux/src/App.js](https://github.com/rohan-paul/Fetch-Github-Profile/blob/master/simple-version-without-using-redux/src/App.js)
10186

102-
******************
87+
---
88+
10389
App.js is Parent and SearchProfile and Profile are the children.
10490

10591
Define a callback in my parent which takes the data I need in as a parameter.
@@ -112,11 +98,10 @@ fetchProfile() is a callback function defined in parent. This takes the data I n
11298

11399
So, I pass this callback function to the child-Component SearchProfile as a prop, with the below line
114100

115-
``<SearchProfile fetchProfileBoundFunction={this.fetchProfile.bind(this)}/>``
116-
117-
Call the callback (fetchProfileBoundFunction) using this.props.[callback] in the child and pass in the data as the argument.
118-
So in SearchProfile I do < this.props.fetchProfileBoundFunction(username) >
101+
`<SearchProfile fetchProfileBoundFunction={this.fetchProfile.bind(this)}/>`
119102

103+
Call the callback (fetchProfileBoundFunction) using this.props.[callback] in the child and pass in the data as the argument.
104+
So in SearchProfile I do < this.props.fetchProfileBoundFunction(username) >
120105

121106
## Even Another Implementation of the above concept in below file -
122107

@@ -125,92 +110,97 @@ So, I pass this callback function to the child-Component SearchProfile as a prop
125110
updateSearchTerm() in parent component Items.js - Fundamental explanation why I need it at all - Because, here, my most fundamental need is to change the searchTerm ( the parent state ) to whatever I type. But then, I am updating this searchTerm from the child and passing down 'searchTerm' as a prop from parent to child. And Prop is immutable, so I can not directly change 'searchTerm' in the Filter.js
126111
So, instead I can give the child a function ( updateSearchTerm() in this file ), that the child can call, and that function can manipulate the state.
127112

128-
129113
```js
130114
class Items extends Component {
131-
132-
constructor(props) {
133-
super(props);
134-
this.state = {
135-
searchTerm: ''
136-
};
137-
}
138-
139-
updateSearchTerm = searchTerm => {
140-
this.setState({
141-
searchTerm
142-
})
143-
}
144-
/* In above, I am using object destructuring syntax. So the single 'searchTerm' is equivalent to doing < searchTerm: searchTerm > Which effectively means tha I am telling setState 'Hey take the searchTerm argument of updateSearchTerm() function and set them to be the value of the key-value pair of state (which is an object and both the key and the value is called 'searchTerm' ).
145-
*/
146-
147-
render() {
148-
149-
const { title, items, onRemove, onToggle } = this.props;
150-
151-
return (
152-
<section className="Items">
153-
<h2>
154-
{title} ({items.length})
155-
</h2>
156-
<Filter searchTerm={this.state.searchTerm} onChange={this.updateSearchTerm} />
157-
{items
158-
.filter(item =>
159-
item.value.toLowerCase().includes(this.state.searchTerm.toLowerCase()),
160-
)
161-
.map(item => (
162-
<Item
163-
key={item.id}
164-
onToggle={onToggle}
165-
onRemove={() => onRemove(item)}
166-
item={item}
167-
/>
168-
))}
169-
</section>
170-
);
171-
}
172-
}
115+
constructor(props) {
116+
super(props);
117+
this.state = {
118+
searchTerm: ""
119+
};
120+
}
121+
122+
updateSearchTerm = searchTerm => {
123+
this.setState({
124+
searchTerm
125+
});
126+
};
127+
/* In above, I am using object destructuring syntax. So the single 'searchTerm' is equivalent to doing < searchTerm: searchTerm > Which effectively means tha I am telling setState 'Hey take the searchTerm argument of updateSearchTerm() function and set them to be the value of the key-value pair of state (which is an object and both the key and the value is called 'searchTerm' ).
128+
*/
129+
130+
render() {
131+
const { title, items, onRemove, onToggle } = this.props;
132+
133+
return (
134+
<section className="Items">
135+
<h2>
136+
{title} ({items.length})
137+
</h2>
138+
<Filter
139+
searchTerm={this.state.searchTerm}
140+
onChange={this.updateSearchTerm}
141+
/>
142+
{items
143+
.filter(item =>
144+
item.value
145+
.toLowerCase()
146+
.includes(this.state.searchTerm.toLowerCase())
147+
)
148+
.map(item => (
149+
<Item
150+
key={item.id}
151+
onToggle={onToggle}
152+
onRemove={() => onRemove(item)}
153+
item={item}
154+
/>
155+
))}
156+
</section>
157+
);
158+
}
159+
}
173160
```
174161

175162
#### And then in <Filter /> child component, I have the below. SO ITS DATA-DOWN ACTIONS-UP KIND OF FLOW
176163

177164
```js
178165
class Filter extends Component {
179-
180-
// note onChange and searchTerm were the props that were handed-down from Items.js
181-
// and so first to access / consume it inside the child I have to do a this.props
182-
// And because this is a Functional Component without constructor, so I don't need to
183-
// declare super(props) before using this.props
184-
// note the onChange() inside handleChange() is NOT an event attribute but the props passed from parent Items.js to
185-
186-
handleChange = event => {
187-
188-
const { onChange } = this.props;
189-
190-
const value = event.target.value;
191-
192-
onChange(value)
193-
}
194-
195-
render() {
196-
197-
const { searchTerm } = this.props;
198-
199-
return (
200-
<input
201-
className="Items-searchTerm"
202-
value={searchTerm}
203-
onChange={this.handleChange}
204-
/>
205-
);
206-
}
166+
// note onChange and searchTerm were the props that were handed-down from Items.js
167+
// and so first to access / consume it inside the child I have to do a this.props
168+
// And because this is a Functional Component without constructor, so I don't need to
169+
// declare super(props) before using this.props
170+
// note the onChange() inside handleChange() is NOT an event attribute but the props passed from parent Items.js to
171+
172+
handleChange = event => {
173+
const { onChange } = this.props;
174+
175+
const value = event.target.value;
176+
177+
onChange(value);
178+
};
179+
180+
render() {
181+
const { searchTerm } = this.props;
182+
183+
return (
184+
<input
185+
className="Items-searchTerm"
186+
value={searchTerm}
187+
onChange={this.handleChange}
188+
/>
189+
);
190+
}
207191
}
208192
```
209193

210-
## Further example of data passing from child to parent by invoking a CB (defined in parent ) in child and updating state in parent
194+
### Reading
195+
196+
#### 1> Example of data passing from child to parent by invoking a CB (defined in parent ) in child and updating state in parent
211197

212198
[https://github.com/rohan-paul/check-pack-items-before-travel/blob/master/src/components/NewItem.js](https://github.com/rohan-paul/check-pack-items-before-travel/blob/master/src/components/NewItem.js)
213199

214-
## React component communication
200+
#### 2> React component communication
201+
202+
https://www.javascriptstuff.com/component-communication/
203+
204+
#### 3> Simple example of passing function (a function that has a setState() it it) from parent to child and invoking it in the child - thereby triggering state change in the parent (e.g. on button-click in the child)
215205

216-
https://www.javascriptstuff.com/component-communication/
206+
[https://www.youtube.com/watch?v=AnRDdEz1FJc](https://www.youtube.com/watch?v=AnRDdEz1FJc)

0 commit comments

Comments
 (0)