I am trying to fetch an api inside ponentDidMount. The api result will be set to the ponent's state and the state mapped and passed to a children ponent.
If I fetch the api using the fetch method inside the ponentDidMount everything works fine:
ponentDidMount(){
fetch(apiToFetch)
.then((result) => result.json())
.then((result) => result.entries)
.then((entries) => this.setState({ ...this.state, entries }))
.catch((error) => console.log(error));
}
if I use fetch inside a method and then call this method inside ponentDidMount nothing is rendered:
ponentDidMount() {
this.fetchApiToEntries(GLOBAL_PORTFOLIO_COLLECTION_API);
}
fetchApiToEntries(apiToFetch) {
fetch(apiToFetch)
.then((result) => result.json())
.then((result) => result.entries)
.then((entries) => this.setState({ ...this.state, entries }))
.catch((error) => console.log(error));
}
I cannot understand what I am missing from the lifecycle. Shouldn't react do the following?
- Init the state
- Render
- Call ponentDidMount
- Rerender
Here is my initial ponent:
export default class Portfolio extends React.Component {
constructor(props) {
super(props);
this.state = {
entries: []
}
}
ponentDidMount() {
this.fetchApiToEntries(GLOBAL_PORTFOLIO_COLLECTION_API);
}
fetchApiToEntries(apiToFetch) {
fetch(apiToFetch)
.then((result) => result.json())
.then((result) => result.entries)
.then((entries) => {
this.setState({
...this.state,
entries
})
})
.catch((error) => console.log(error));
}
render() {
return (
<Fade bottom>
<div className="Portfolio">
<div className="Portfolio__title"><h4 className="color--gradient text--spacing">WORKS</h4></div>
<OwlCarousel {...options}>
{this.state.entries.map((item) => (
<PortfolioElement item={item} />
))}
</OwlCarousel>
<AnchorLink href='#contact'><Button className="contact-button btn--gradient slider-button Services__button">Let's get in touch</Button></AnchorLink>
</div>
</Fade>
)
}
}
PortfolioElement is the actual ponent not being rendered. Any advice? Thank you.
Edit: both methods are not rerendering the ponent the right way (...something I didn't expect: I don't know why but if I call them twice in ponentDidMount the ponent will render the right way). I think I am missing something in the state.
I have no error in the console and this is how I set my initial state:
this.state={entries:[]}
and this is what the actual entries looks like from the console:
entries:
[0:{credits: "..."
description: "..."
featuredImage: {path: "portfolio/01.jpg"}
firstImage: {path: "portfolio/firstimage.jpg"}
secondImage: []
slug: "..."
tasks: (5) [{…}, {…}, {…}, {…}, {…}]
title: "..."
_by: "5beae6553362340b040001ee"
_created: 1542123322
_id: "5beaef3a3362340bf70000b4"
_mby: "5beae6553362340b040001ee"
_modified: 1542149308
},
1:{...}
]
My state after the fetch is the same way.
UPDATE I figured out that the the problem is: when the state changes the ponent is not rerendering the child with the correct props. I called the API in an higher order ponent passed down the props and added a ponentWillUpdate method forcing a state refresh that rerenders the ponent. Not the ideal solution but I am not figuring out other ways until now. Any advice?
I am trying to fetch an api inside ponentDidMount. The api result will be set to the ponent's state and the state mapped and passed to a children ponent.
If I fetch the api using the fetch method inside the ponentDidMount everything works fine:
ponentDidMount(){
fetch(apiToFetch)
.then((result) => result.json())
.then((result) => result.entries)
.then((entries) => this.setState({ ...this.state, entries }))
.catch((error) => console.log(error));
}
if I use fetch inside a method and then call this method inside ponentDidMount nothing is rendered:
ponentDidMount() {
this.fetchApiToEntries(GLOBAL_PORTFOLIO_COLLECTION_API);
}
fetchApiToEntries(apiToFetch) {
fetch(apiToFetch)
.then((result) => result.json())
.then((result) => result.entries)
.then((entries) => this.setState({ ...this.state, entries }))
.catch((error) => console.log(error));
}
I cannot understand what I am missing from the lifecycle. Shouldn't react do the following?
- Init the state
- Render
- Call ponentDidMount
- Rerender
Here is my initial ponent:
export default class Portfolio extends React.Component {
constructor(props) {
super(props);
this.state = {
entries: []
}
}
ponentDidMount() {
this.fetchApiToEntries(GLOBAL_PORTFOLIO_COLLECTION_API);
}
fetchApiToEntries(apiToFetch) {
fetch(apiToFetch)
.then((result) => result.json())
.then((result) => result.entries)
.then((entries) => {
this.setState({
...this.state,
entries
})
})
.catch((error) => console.log(error));
}
render() {
return (
<Fade bottom>
<div className="Portfolio">
<div className="Portfolio__title"><h4 className="color--gradient text--spacing">WORKS</h4></div>
<OwlCarousel {...options}>
{this.state.entries.map((item) => (
<PortfolioElement item={item} />
))}
</OwlCarousel>
<AnchorLink href='#contact'><Button className="contact-button btn--gradient slider-button Services__button">Let's get in touch</Button></AnchorLink>
</div>
</Fade>
)
}
}
PortfolioElement is the actual ponent not being rendered. Any advice? Thank you.
Edit: both methods are not rerendering the ponent the right way (...something I didn't expect: I don't know why but if I call them twice in ponentDidMount the ponent will render the right way). I think I am missing something in the state.
I have no error in the console and this is how I set my initial state:
this.state={entries:[]}
and this is what the actual entries looks like from the console:
entries:
[0:{credits: "..."
description: "..."
featuredImage: {path: "portfolio/01.jpg"}
firstImage: {path: "portfolio/firstimage.jpg"}
secondImage: []
slug: "..."
tasks: (5) [{…}, {…}, {…}, {…}, {…}]
title: "..."
_by: "5beae6553362340b040001ee"
_created: 1542123322
_id: "5beaef3a3362340bf70000b4"
_mby: "5beae6553362340b040001ee"
_modified: 1542149308
},
1:{...}
]
My state after the fetch is the same way.
UPDATE I figured out that the the problem is: when the state changes the ponent is not rerendering the child with the correct props. I called the API in an higher order ponent passed down the props and added a ponentWillUpdate method forcing a state refresh that rerenders the ponent. Not the ideal solution but I am not figuring out other ways until now. Any advice?
Share Improve this question edited Nov 14, 2018 at 16:30 Filippo Rivolta asked Nov 14, 2018 at 13:46 Filippo RivoltaFilippo Rivolta 551 silver badge7 bronze badges 5- 1 I know the method binding in the constructor is missing. – Filippo Rivolta Commented Nov 14, 2018 at 13:49
-
3
Shouldn't react do the following? - it should. if I use fetch inside a method and then call this method inside ponentDidMount nothing is rendered - this is unlikely. These two
ponentDidMount
snippets should behave exactly the same way, as long asapiToFetch
is the same. Consider providing a way to replicate the problem. – Estus Flask Commented Nov 14, 2018 at 13:54 - 1 It should work, please check console log for any error or replicate this on codepen so it will be easy for other to debug the issue – Bheru Lal Lohar Commented Nov 14, 2018 at 14:07
-
Can you do a log and show us the structure of
result.entries
? Are you getting error in the console, network or browser? – Abrar Commented Nov 14, 2018 at 14:08 - I get no errors, and I have to edit my question: both methods give the same results. I think I am missing something in my initial state. I will update the question. – Filippo Rivolta Commented Nov 14, 2018 at 14:21
2 Answers
Reset to default 2Idk what your api response is but I tested your code with a fake API and changed
fetchApiToEntries(apiToFetch){}
to Arrow Function (Arrow Function)
fetchApiToEntries = (apiToFetch) => {}
and it's working fine.
Full Example:
export default class Portfolio extends React.Component {
constructor(props) {
super(props);
this.state = {
entries: []
}
}
ponentDidMount() {
this.fetchApiToEntries('https://jsonplaceholder.typicode./posts');
}
fetchApiToEntries = (apiToFetch) => {
fetch(apiToFetch)
.then(result => result.json())
.then((entries) => {
this.setState({
...this.state,
entries
})
})
.catch((error) => console.log(error));
}
render() {
const {entries} = this.state;
console.log(entries);
return (
// Everything you want to render.
)
}
}
Hope it helps you.
do you need to bind fetchApiToEntries in the constructor or use fat arrows?
this.fetchApiToEntries = this.fetchApiToEntries.bind(this);
sorry I cant ment not enough rep
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744750263a4591551.html
评论列表(0条)