-
Notifications
You must be signed in to change notification settings - Fork 49.4k
Description
Do you want to request a feature or report a bug?
Reporting a possible bug
What is the current behavior?
My app renders fine with no errors but I can't seem to figure out why I keep getting this warning:
index.js:1446 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in ArtistProfile (at App.js:51)
in component (created by Route)
api-calls.js (Here's a link):
https://github.com/ryansaam/litphum/blob/master/src/api-calls.js
App.js
class App extends Component {
constructor(props) {
super(props)
this.state = {
user: {},
spotifyAPI: {}
}
}
componentDidMount() {
if (user_token) {
sessionStorage.setItem('access_token', user_token)
this.setState({
spotifyAPI: new spotifyAPI( user_token )
})
} else if (sessionStorage.getItem('access_token')) {
this.setState({
spotifyAPI: new spotifyAPI( sessionStorage.getItem('access_token') )
})
}
}
componentDidUpdate(prevProps, prevState) {
if (this.state.spotifyAPI !== prevState.spotifyAPI)
this.state.spotifyAPI.getUserProfile()
.then(data => this.setState({user: data}))
}
render() {
const { user, spotifyAPI } = this.state
const token = sessionStorage.getItem('access_token')
return (
<Router>
<div className="App">
{ (spotifyAPI.user_token && user)
? (<div className="logged-in">
<div style={{width: "250px", height: "100%", position: "relative", float: "left"}} >
<Nav image={user.images ? user.images[0].url : null} user={user} />
</div>
<main id="main">
<Route path={`/${user.type}/${user.id}`} exact component={() => <Home spotifyAPI={spotifyAPI} />} />
<Route path="/artist/" component={() => <ArtistProfile spotifyAPI={spotifyAPI} />} />
</main>
</div>)
: <div onClick={() => window.location = "http://localhost:8888/login"} >log in</div>
}
</div>
</Router>
);
}
}
ArtistProfile.js
const ArtistProfile = props => {
const [artistData, setArtistData] = useState(null)
const { getArtist, getArtistAlbums, getArtistTopTracks } = props.spotifyAPI
useEffect(() => {
const id = window.location.pathname.split("/").pop()
const ac = new AbortController()
console.log(id)
Promise.all([
getArtist(id, ac),
getArtistAlbums(id, ["album"],"US", 10, 0, ac),
getArtistTopTracks(id, "US", ac)
])
.then(response => {
setArtistData({
artist: response[0],
artistAlbums: response[1],
artistTopTracks: response[2]
})
})
.catch(ex => console.error(ex))
return () => ac.abort()
}, [])
console.log(artistData)
return (
<div>
<ArtistProfileContainer>
<AlbumContainer>
{artistData ? artistData.artistAlbums.items.map(album => {
return (
<AlbumTag
image={album.images[0].url}
name={album.name}
artists={album.artists}
key={album.id}
/>
)
})
: null}
</AlbumContainer>
</ArtistProfileContainer>
</div>
)
}
What is the expected behavior?
If you can see in ArtistProfile.js I am using a clean up function that aborts when the component does unmount. The fetch would be aborted and state shouldn't update but for some reason I am still getting this memory leak warning.
What I am expecting is for the warning to no longer throw because am using a clean up function that aborts the fetch.
Link to repo: https://github.com/ryansaam/litphum
- Files mentioned
App.js: https://github.com/ryansaam/litphum/blob/master/src/App.js
ArtistProfile.js: https://github.com/ryansaam/litphum/blob/master/src/components/ArtistProfile.js
api-calls.js: https://github.com/ryansaam/litphum/blob/master/src/api-calls.js
My stackoverflow question: https://stackoverflow.com/questions/54954385/react-useeffect-causing-cant-perform-a-react-state-update-on-an-unmounted-comp/54964237#54964237
Which versions of React, and which browser
React 16.8.2
Latest version of Chrome