Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array contents not rendering in ReactJS

I am still fairly new to React. I am trying to map the contents of an array in ReactJS. Currently, I am having no results render. Here is the section of code I am using to map the array contents:

return (
        <div>
            {this.state.errors.map( (error, index) => 
                <div key={index} className="alert alert-danger" role="alert">
                    {error}
                </div>
            )}
        </div>
       )

Here is how I am initializing the state:

this.state = {
    workoutId:'',
    daysOfWeek:[],
    name:'',
    trainingPlan:'',
    errors: []
}

And here is where I am populating the errors array:

if(this.state.daysOfWeek.length < 1) {
    this.state.errors.push('Must select at least 1 day to perform workout');
}
if(this.state.workoutId === '') {
    this.state.errors.push('Please select a workout to edit');
}

console.log(this.state.errors);

I am seeing that the array is being populated with those strings on the console.log. My understanding of React is that the component will re-render itself when changes are made. Is that correct? Anyway, can someone explain to me why my array contents will not render? I have tried mapping based on if the length of the errors array is greater than 0, which did not work either.

like image 722
Nick D Avatar asked Jun 10 '26 08:06

Nick D


2 Answers

In React, you must never assign to this.state directly. Use this.setState() instead. The reason is that otherwise React would not know you had changed the state.

The only exception to this rule where you assign directly to this.state is in your component's constructor.

like image 154
Alexander van Oostenrijk Avatar answered Jun 11 '26 21:06

Alexander van Oostenrijk


You cannot modify your state object or any of the objects it contains directly; you must instead use setState. And when you're setting state based on existing state, you must use the callback version of it; details.

So in your case, if you want to add to the existing this.state.errors array, then:

let errors = [];
if(this.state.daysOfWeek.length < 1) {
    errors.push('Must select at least 1 day to perform workout');
}
if(this.state.workoutId === '') {
    errors.push('Please select a workout to edit');
}
if (errors.length) {
    this.setState(prevState => ({errors: [...prevState.errors, ...errors]}));
}

If you want to replace the this.state.errors array, you don't need the callback form:

let errors = [];
if(this.state.daysOfWeek.length < 1) {
    errors.push('Must select at least 1 day to perform workout');
}
if(this.state.workoutId === '') {
    errors.push('Please select a workout to edit');
}
if (errors.length) { // Or maybe you don't want this check and want to
                     // set it anyway, to clear existing errors
    this.setState({errors});
}
like image 30
T.J. Crowder Avatar answered Jun 11 '26 20:06

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!