Reputation: 4616
I am completely new to ReactJS. I have a component (Component A) where I want to click a button and fetch a token from an API using AJAX call. Once the fetch is successful I need to pass it to another component (Component B) and render it conditionally (https://reactjs.org/docs/conditional-rendering.html).
Both Component A and B are nested within a single parent component and should render conditionally.
class Parent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<ComponentA />
or
<ComponentB>
</div>
);
}
}
Expected result:
ComponentA
should fetch the token within itself and pass to its Parent
, there by notifying to replace ComponentA
and render ComponentB
.
Code I tried:
I took an example from here: https://codepen.io/gaearon/pen/QKzAgB?editors=0010 and How to pass data from child component to its parent in ReactJS? and wrote the below code.
class ComponentA extends React.Component {
constructor(props){
super(props);
this.handleGenerateToken = this.handleGenerateToken.bind(this);
}
handleGenerateToken(){
console.log("gen token");
axios({
method: 'post',
url: 'https://<token_url>',
mode: 'no-cors'
}).then((result) => {
if(result.status === 200){
console.log({token:result.data});
this.props.onGenerateToken({token:result.data}); //it fails here
}else{
console.log("Error generating token. Status code: " + result.status);
}
});
}
render(){
return(
<div>
<div id="details" className="div-center">
some ui
<div>
<a id="btnStart" onClick={this.handleGenerateToken} className="waves-effect waves-light btn secondary-content">Start</a>
<a id="btnReset" className="waves-effect waves-grey btn blue-grey lighten-5 black-text outline secondary-content">Reset</a>
</div>
</div>
</div>
);
}
}
Problem is I get the token but unable to set it to the props using this.props
. I get below which seems like this
is not accessible.
Uncaught (in promise) TypeError: _this4.props.onGenerateToken is not a function at :182:26
I tried creating an extra variable _self
and assign this
outside the Promise
scope of the AJAX call but that didn't work.
I am not sure if I am doing this correctly. Please let me know if I can explain in more detail.
Upvotes: 0
Views: 92
Reputation: 3059
A simple example :
Let <ComponentA/>
be your component:
handleGenerateToken(){
console.log("gen token");
axios({
method: 'post',
url: 'https://<token_url>',
mode: 'no-cors'
}).then((result) => {
if(result.status === 200){
console.log({token:result.data});
this.props.onGenerateToken({token:result.data}); //it will have a handler in wrapper(parent) component
}else{
console.log("Error generating token. Status code: " + result.status);
}
});
}
Let <Parent/>
be the component you have wrapped this <ComponentA/>
and <ComponentB/>
. Conditionally render components on basis of boolean like flag isTokenAvailable
defined in state
In <Parent/>
's render method :
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
isTokenAvailable: false,
token:null
};
}
render() {
const isTokenAvailable = this.state.isTokenAvailable;
return (
<div>
{isTokenAvailable ? (
<ComponentB />
) : (
<ComponentA
onGenerateToken={(token) => {
this.setState({ isTokenAvailable: true, token });
}}
/>
)}
</div>
);
}
}
Upvotes: 1
Reputation: 524
Change this.handleGenerateToken
to this.handleGenerateToken()
or handleGenerateToken(){
to handleGenerateToken = () => {
And instead of changing props, just use state :)
state = { token: undefined };
constructor(props){
super(props);
this.handleGenerateToken = this.handleGenerateToken.bind(this);
}
and then just simply
this.setstate({token:result.data});
Then you can render it conditionaly
render(){
if(this.state.token === undefined){
return <Text>Oh, Token is undefined</Text>
}
return <Text>Token is defined</Text>
}
Upvotes: 0