Reputation: 9763
I am trying to write a wrapper component around an API call to render "loading" if the api hasnt updated. Im very new to react, but I can t seem to figure out why the state isnt being passed to the ApiResp component:
Here is the console.log of the state changes..... why is the final apiResp in console.log undefined?
App.js
class App extends React.Component {
async componentDidMount() {
let xx = await axios.get(apiUrl)
console.log(`componentDidMount`, xx)
this.setState({ loading: false, body: xx });
}
render() {
console.log(`rendering ComponentLoading`, this.state)
const DisplayComponent = ComponentLoading(ApiResp)
return (
<div className="App">
<header className="App-header">
<img src={face} /*className="App-logo"*/ alt="face-img" />
</header>
<br></br>
<div>
<DisplayComponent isLoading={AppState.loading} body={AppState.body} />
</div>
</div>
);
}
}
export default App;
ComponentLoading:
import React from 'react';
function ComponentLoading(Component) {
return function WihLoadingComponent({ isLoading, ...props }) {
if (!isLoading) return <Component {...props} />;
return (
<p style={{ textAlign: 'center', fontSize: '30px' }}>
Loading
</p>
);
};
}
export default ComponentLoading;
apiResp.js
import React from 'react';
const ApiResp = (data) => {
console.log(`apiResp:`, data)
if (!data || data.statusCode !== 200) {
return <p>Err: {JSON.stringify(data)}</p>;
}
else
return (
<div>
<h3>obj:</h3>
{JSON.stringify(data)}
</div>
);
};
export default ApiResp;
Upvotes: 2
Views: 48
Reputation: 203408
ComponentLoading
is a Higher Order Component. const DisplayComponent = ComponentLoading(ApiResp)
is decorating the ApiResp
component:
const ApiResp = (data) => {
console.log(`apiResp:`, data)
if (!data || data.statusCode !== 200) {
return <p>Err: {JSON.stringify(data)}</p>;
}
else
return (
<div>
<h3>obj:</h3>
{JSON.stringify(data)}
</div>
);
};
and returning a component you've called DisplayComponent
.
As a component ApiResp
is consuming a props object called data
and only accesses a statusCode
prop.
DisplayComponent
is passed two props:
<DisplayComponent isLoading={AppState.loading} body={AppState.body} />
AppState
isn't defined in the parent component but it seems this.state
has the values you want passed to DisplayComponent
.
Access and pass the correct object to props.
<DisplayComponent
isLoading={this.state.loading}
body={this.state.body}
/>
I suggest also moving the const DisplayComponent = ComponentLoading(ApiResp)
declaration out of the render method, and also outside the App
component.
const DisplayComponent = ComponentLoading(ApiResp);
class App extends React.Component {
state = {
loading: true,
body: null,
};
async componentDidMount() {
let xx = await axios.get(apiUrl)
console.log(`componentDidMount`, xx)
this.setState({ loading: false, body: xx });
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={face} /*className="App-logo"*/ alt="face-img" />
</header>
<br></br>
<div>
<DisplayComponent
isLoading={this.state.loading}
body={this.state.body}
/>
</div>
</div>
);
}
}
Upvotes: 1