I've created on form in child component. After submitting that form using jquery ajax method ($.ajax) I am retriving some data in json format. I want to put that data in my parent component's state. So, is there any method in react.js for passing value or data from child component to its parent component?
Thank you..
The way to do this without some kind of Flux implementation is to create a function on the parent element that handles the response/data from the child and pass that function as a prop. Then call that function from the child. Something like this:
Parent:
handleResponse(data) {
console.log(data)
}
render() {
return(
<div>
<Child handleResponse={this.handleResponse} />
</div>
);
}
then in the child:
handleAjax() {
$.get(url).then( (response) => {
this.props.handleResponse(response)
});
}
this all assumes ES6 syntax. Using ES5 you're going to have to use bind or var that = this to scope everything correctly.
Related
Within Session() I want to access stateABC, which is in Item5().
The setup of my code looks like this:
Session.js:
function Session() {
//get handleRender(item).props.stateABC here
return (
<View>
{handleRender(item)}
</View>
);
}
handleRender.js:
export function handleRender(item) {
if(item == "Item5"){
return (
{Item5()}
);
}
}
Item5.js:
export function Item5() {
const [stateABC, setStateABC] = useState("123");
return (
....
);
}
I tried to get the value in Session() by using handleRender(item).props.stateABC, but all I get is an empty value.
Is it possible to receive properties from a function like that or are props only accessible in class components?
Any help is appreciated.
Thanks
If you need to access to stateABC value from Session component you have to pass a callback prop down from Session to Item5 and call it every time you update stateABC with setStateABC, passing the new value to the callback.
This is the simplest approach, you could also use React Context API or even something like Redux if you think that your app will grow in complexity.
Also, the approach that you tried to use is a bad idea. It works only in class component but in any case you should not use it, it's a bad thing to access props directly.
I wish to send a message to a React component to request it do something other than re-render.
Specifically, I wish to request a component containing a grid to save the grid data.
I know that I can send data into a component via props and that change of state will trigger re-rendering.
However, how can I pass an event rather than data into the component?
The solution I am currently using is to use events: https://github.com/primus/EventEmitter3. My concern with this approach is that it is not linked to the React lifecycle and as such, events might reach the component at an inappropriate stage in the component lifecycle.
Is there an idiomatic way that I can do this just using React?
"However, how can I pass an event rather than data into the component?"
Not exactly sure what you mean. If I think I understand what you're trying to do, you can pass a function down to the lower component which gets fired off on the parent level:
const Child = ({ handleChildClick }) => {
const someData = { name: "John", age: 69 };
// Where someData can either be from state or a variable (just using functional component as it's easier to read imo)
return (
<div>
<button onClick={handleChildClick(someData)}>Click me</button>
</div>
);
};
const Parent = () => {
const childClicked = data => {
console.log("Data from child: ", data);
};
return (
<div>
<Child handleChildClick={childClicked} />
</div>
);
};
So when the child's event is fired off
I don't want to have a handle refresh function in every single screen in my project, so I created a Helper.js to handle this. This function has this.setState and another call for a function inside the screen component. This is what I got so far but it returns an error.
Exported function
export function handleRefresh(component) {
const {page, refreshing} = component.state
component.setState(
{
page:1,
refreshing:true
},
() => {
component.makeRemoteRequest();
}
);
};
and I call it in the component like this:
<FlatList
...
onRefresh={()=> handleRefresh(this)}
refreshing={this.state.refreshing}
...
/>
I saw that you can pass "this" as a param, but the error still says it is undefined.
setState shall be within that screen always where you are using FlatList because after making API you have to update and control the state of that screen.
All the states will be in the component where FlatList using.
Use case are not logical in my view. You can try to create a helper function which accepts different functions params like: page, isRefreshing and return the API response and also the API url and datapost will also be dynamic. Because you want to use it in many areas. It will be difficult to maintain.
So, If you like then use redux what you want.
https://snack.expo.io/#prashen/flatlist-onrefresh
You can do in this way.
class AComponent {
...
render() {
const thisComponent = this;
<FlatList
...
onRefresh={()=> handleRefresh(thisComponent)}
refreshing={this.state.refreshing}
...
/>
}
};
All this. uses refer a same class or function. Only use IF i'ts a child function, component or method.
I'ts don't work out of class function original, you can make a bridge for share data or status.
You can use redux for it and using stores for update screen state.
I have a function in a component which I want to call in a child component.
This is the function in the parent component:
handleFilterGroupsQuery = queryObject => {
return queryObject;
}
I have binded it to this in the constructor (in parent component):
constructor(props) {
super(props);
this.handleFilterGroupsQuery = this.handleFilterGroupsQuery.bind(this);
}
Within the render method of this component, I am passing down this function to a child component like so:
<FilterGroupsSection
handleFilterGroupsQuery={(queryObject) => {this.handleFilterGroupsQuery(queryObject)}}
/>
In the FilterGroupsSection (child) component, I am trying to call this function like so:
let test = 'test'
console.log(this.props.handleFilterGroupsQuery(test));
This displays 'undefined' in the console. I can't figure out why the parameter value is not being passed correctly.
Appreciate any advice.
You have 2 options. Just remove additional {} in function binding to your child component or use return:
handleFilterGroupsQuery={(queryObject) => this.handleFilterGroupsQuery(queryObject)}
or
handleFilterGroupsQuery={(queryObject) => { return this.handleFilterGroupsQuery(queryObject)}}
One good solution would be to pass the argument and the function separately:
<Parent
handleFilterGroupsQuery={this.handleFilterGroupsQuery}
queryObject={queryObject}
/>
Then, you can easily bind the argument every time you call the function at your child component:
this.props.handleFilterGroupsQuery.bind(null, queryObject);
Otherwise, the unnamed inline functions and object will have new references and trigger a complete re-render of the component tree below.
I found out that my argument passed from parent to child component through refs is either undefined or an actual event instead of what I passed in.
What is the right way to actually pass argument from parent to child component's function? I am using refs but seems its not really passing anything in term of function argument.
I show the case here:
https://codepen.io/adamchenwei/pen/gLMaPo/?editors=0010
Basically if you see the line where I wrote console.log('child argument should be string'); it should be an argument actually passed instead of an event.
I wonder if I did things wrong.
For this scenario, I NEED to evaluate event in parent component and decide how I want to run the child function, with specific arguments passed in accordingly.
There are only two way to access parent props in child component. you can achieve this in following two ways:-
Pass values into child component from parent via props
Set values in state and dispatch action from child to fetch values from state.
Instead of using ref, I would use state and props:
parentDoThing(event) {
const lifeTerms = {
heaven: 'yeeeeey',
hell: 'nooooooo',
}
if(event) {
this.setState({ lifeTerms: heaven });
} else {
this.setState({ lifeTerms: hell});
}
}
render() {
return (
<section className="parent-comp"
onClick={this.parentDoThings}>
<ChildComponent
lifeTerms={this.state.lifeTerms}/>
<h1> Whats in App {this.state.text}</h1>
</section>
);}
And on child component:
render() {
return (
<section className="child">
<section>this life is {this.state.life} </section>
<button onClick={this.doChildThings.bind(this, this.props.lifeTerms)}> Button </button>
</section>
);
Resolved my issue by using componentWillUpdate in combine with using parent level state passed into child as props to trigger event inside the child, because I do not want any trigger inside the child to trigger the change provided by the parent.