Reputation: 6815
In following code cityNameLength
is a number and represent the length of the name of one city.
My goal is to render multiple elements based on cityNameLength
value.
So if cityNameLength
is equal to 5 I'd like to have 5 span
elements.
This is what I've have:
class myCitiesClass extends Component {
constructor(props) {
super(props);
this.state = {cLength: 0};
this.setState({ cLength: this.props.cityNameLength });
}
renderDivs() {
var products = []
var cNameLength = this.state.cLength
for (var p = 0; p < cNameLength; p++){
products.push( <span className='indent' key={p}>{p}</span> );
}
return products
}
render() {
return (
<View>
<Text>City name length: {this.props.cityNameLength}</Text>
<View>{this.renderDivs()}</View>
</View>
);
}
}
This is the error I get:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op.
Upvotes: 1
Views: 1017
Reputation: 3826
You cannot use this.setState
in the constructor. And fortunately, you don't need to. State could be set to the proper value right in the assignment:
constructor(props) {
super(props);
this.state = { cLength: this.props.cityNameLength };
}
However, this code is not good too. Assigning state from props is not necessarily the mistake, but you have to know well what you're doing and why (thing is that props could be changed from the top level component at any time, and you will have to keep state in sync with overridden componentWillReceiveProps()
to make your component work right). If you doubt you do, you should avoid it.
In your case it should be easy as you don't need state at all. Remove constructor, and use this.props.cityNameLength
instead of this.state.cLength
.
And when you modify state from componentDidMount()
you are supposed to know very well what you're doing (because you're triggering another render right after your component is just rendered - why?). In 99% of cases it's the mistake. Not that fatal as doing so in componentDidUpdate
, though.
Upvotes: 0
Reputation: 8936
There are two ways you can do this. If you want to render the spans before the component is mounted, get rid of the setState and just do this in the constructor:
this.state= {cLength: this.props.cityNameLength };
If you want the component to mount first - then remove the setState from the constructor and move it into componentDidMount()
:
componentDidMount() {
this.setState({ cLength: this.props.cityNameLength });
}
Upvotes: 1