Can't Call setState on an unmounted component even after componentDidMount - javascript

I'm running into a strange issue with React Router.
I keep getting the warning "Can't call setState (or forceUpdate) on an unmounted component..." even though I can prove that the component in question is hitting its componentDidMount lifecycle method.
I'm perfectly fine with ignoring warnings. The thing is, the app isn't working properly because of this.
Current state of my flailing about:
https://github.com/tomizechsterson/chargen-ui
After starting the app, if you click on the 'AD&D 2nd Edition' link, you can select entries in the table just fine. It's after you navigate away (to either 'Home' or 'D&D 3.5') and back that you can no longer select entries and the warning pops up in the console.
I've tried going through the React Router docs, but wasn't able to figure out what I needed to know to solve this.
Please suggest.

Turns out that converting a lower-level component to a functional component in my hierarchy avoids this issue. Not sure why, but it's removed my roadblock, so there it is

Related

ComponentWillMount can't find an variable

I have already created a react native CLI project. Now every time when user come to my screen I want to update some value. In my home screen, I have three top tabs. When the user clicks on the 3rd tab. I need to update some values every time.
For those three tabs, I am using: ScrollableTabView
import ScrollableTabView, { DefaultTabBar } from 'react-native-scrollable-tab-view';
I used this below code for every time to update the values. But this is calling only for one time:
useEffect(() => {
alert('i called');
})
Then i tried :
import React, { useEffect, Component } from 'react';
componentWillMount( () => {
alert('called ');
})
But I am getting error like cant the variable componentWillMount.
How can I solve? Please help.
Thanks.
It seems like you are using the new React Native way by using hooks and functional components only.
It is not possible to use reacts lifecycle methods anymore - you will have to write your own componentWillMount code. Take a look at the docs or take a look at this answer:
How to use componentWillMount() in React Hooks?
~Faded
So, going back to React basics. There are 2 ways of declaring a component: using a Class based component or using a functional component which you are clearly using.
Before React Hooks, we couldn't have state in our functional components, that means that you cannot use the LifeCycle Methods from a Class based Component. I really suggest you to read the documentation. Instead, we can use hooks to get the same behavior.
Now, the useEffect hook will receive 2 parameters: the first one is the callback we are going to execute, and the second is an array of dependencies that will trigger that hook. It means that the hook will watch for changes in the variables you put in your array. Since you are not declaring an array of dependencies, the hook will be executed on every render.
So, what's exactly the problem? The problem is that declaring your tabs with react-native-scrollable-tab-view won't unmount the components for each tab, there are no variations, that's because your alert log is only being logged once. Because there are no more renders, just once.
Looking at the docs, you might be using onChangeTab method, which apparently will be called when changing the tab.

Change Vuex state right after hydration?

My Vue application uses server-side rendering. When the app has loaded and hydrated, I'd like to detect a condition on the client and then commit a mutation.
If I touch the state before mounting the app, this warning is printed - as expected:
[Vue warn]: The client-side rendered virtual DOM tree is not matching
server-rendered content. This is likely caused by incorrect HTML
markup, for example nesting block-level elements inside <p>, or
missing <tbody>. Bailing hydration and performing full client-side
render.
I thought I'd find a hook that would be called right after the hydration is done.
I tried committing the mutation in the mounted hook of the main component. I also tried doing it after app.$mount(...), and with Vue.nextTick(). All of these were too early: in each of these cases, I get the above warning.
I found two workarounds:
adding a mounted hook in the child component that will render differently with the modified state. That hook is called after the parent hook. Okay for now, since I only need to use it one place. But will get dirty when I need it in two different components.
using an obscure setTimeout(). Breaks easily, since I found no easy way to check whether the hydration is complete, so I can't poll. (The data-server-rendered attribute is removed when hydration begins.)
Any ideas how this could be solved properly?

Render after componentWillReceiveProps and before componentDidUpdate

Here's my problem:
I'm new at reactjs and I'm trying to make this app using SWAPI (swapi.co). For now I need to list characters and some info about them. The problem is I have this component called SelectedCharacter that returns some info about a character that was selected in a div.
The moment a character is passed through props to this component, I get a response via xmlhttp and the info is displayed. The thing is that I want to put a "Loading..." message while the data is fetched. This is how I was trying to figure it out:
I set up the componentWillReceiveProps function, where I test if I'll need to load stuff and the componentDidUpdate, where I fetch the data from this api and update the status.
I know, from react life cycle, that a render is called between componentWillReceiveProps and componentDidUpdate, and it indeed is.
I expected, then, that if I did this:
render() {
if (criteria) {
return <div>Loading...</div>
}
}
The thing is: even if this criteria is true (I tested it using console.log()), the message doesn't show until the next re-render. Am I doing anything too wrong here? If it helps, my code is at github.com/piubellofelipe/StarWars, the problem is at the selected_characters.js, in the src paste.
Thanks
I've been looking at your code, trying to work this out for you and I don't have any concrete answers for you, but I've noticed a few things that may be making things a bit unpredictable.
1. Calling forceUpdate
componentWillReceiveProps(){
this.setState({loading:true})
this.forceUpdate();
}
Calling setState will trigger a render, so the call the forceUpdate is not required here. This means there are more renders occurring than you might expect.
I believe this may be the cause of your issue for a pretty complicated reason. From the setState docs
... setState() is also asynchronous, and multiple calls during the same cycle may be batched together.
And from the forceUpdate docs
Calling forceUpdate() will cause render() to be called on the component...
My theory is that the call render triggered by setState, asynchronously setting loading to true, is being delayed and the one from forceUpdate is sneaking in first, while loading is still false.
2. Updating props
this.props.selected.moviesList = moviesListNames;
Components should never, ever, update their own props. Usually, this would be stored in state instead.
For more details on this, read this section of the docs and this answer.
3. Importing axios, but not using it
import axios from 'axios'
This one isn't really an issue (other than an unused import), and might just be preparation for where you're heading. axios gives a much nicer developer experience than XMLHttpRequest (in my opinion) for http requests and will clean up the fetchData function a lot, which will make troubleshooting easier.
I hope this helps a bit, and you're enjoying React. Feel free to follow up on any of these points in the comments or as new questions.

reactjs lifecycle is there a visual flowchart?

I'm running into alot of issues with reactjs mainly because I'm not exactly sure of the component lifecycle and at precisely what point things like setState do things.
I am aware there is a page titled "Component Lifecycle" but I need a much more detailed visual diagram showing how reactjs lifecycle works, in particular showing where and when setState does things.
Is there such a diagram?
Could this be useful to you? It shows where setState() can be called and where it cannot. It also shows what lifecycle methods receive the new state.

call forceUpdate() on component when redux state updates

I have an issue with redux state being updated successfully, but react component not re-rendering, after some research I believe [forceUpdate()][1] can solve my issue, but I am unsure of correct way to implement it i.e. after redux state updates. I tried looking up examples on github, but had no luck.
As others have said, forceUpdate() is basically a hack. You get updates for free whenever the props and state change. React and Redux work seamlessly together, so avoid any such hacks.
If your Redux state is updating correctly and your React view isn't, then it's most likely that you're not updating in an immutable fashion. Check your reducers.
It is possible that your issues is that the state you are updating is not a top level property. react calls a "shallowEqual" method to tell whether the props have updated. This means all top level properties, but if you are changing a deeper property and all the top level ones are the same then you will not rerender.
I'm not sure if this would be the case with redux maybe it's doing something more sophisticated but I know that is the workflow in react. It's worth taking a look.
That's not the solution you want.
Without looking at your code, it's impossible to tell what's actually wrong, but forceUpdate is not the solution. React will re-render if new data is placed in the state or props. If you're not re-rendering, it means you're data isn't getting all the way through.
Redux already doing forceUpdate with connect decorator. Maybe you miss this point in your component. This behaviour is explained on the Usage with React section of official documentation.

Categories

Resources