Skip to content
Advertisement

Unsure as to why conditional rendering is not working in react

I’m trying to have something conditionally rendered based on the length of the array I receive from the backend which contain objects. If the length is 0, then I want it to say something like “no projects” and if the length is > 0 then I want it to just display the projects on the screen. Here is what I tried doing:

// Main component handling the filter body
class FilterBody extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            // Variables
            projects: null,
            assignment_type: "",
            sdg: [""],
            theme: [""],
            keywords: [""],
            orginization: "",

            jsonLength: 1,
            // Select module features
            isClearable: true,
            isSearchable: true,
        };
  
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    // Handling all 3 input submissions
    handleSubmit(event) {
        event.preventDefault();

        const data = {
            sdg: this.state.sdg, 
            assignment_type: this.state.assignment_type,
            orginization: this.state.orginization,
            keywords: this.state.keywords
        }

        fetch(`/api/projects/filter?sdg=${encodeURIComponent(data.sdg)}&assignment_type=${encodeURIComponent(data.assignment_type)}&orginization=${encodeURIComponent(data.orginization)}&keywords=${encodeURIComponent(data.keywords)}`, {
            method: "GET",
            headers: {
                    'Content-Type': 'application/json;charset=utf-8', 
                },
        })
            .then(response => response.json())
            .then(json => (this.setState({projects: json}), {jsonLength: json.length}))
            .then(jsonLength => console.log(jsonLength)) // DEBUG
        
    }

    async componentDidMount() {
        const response = await fetch('/api/projects')
        const json = await response.json()

        if (response.ok) {
            this.setState({projects: json})
        }
        
    }

    projectDisplay() {
        return (
            <>
                <div className="content">
                    {this.state.projects && this.state.projects.map((project) => (
                        <ProjectDetails key={project._id} project={project}/>
                    ))}
                </div>
            </>
        )
    }


    render() {
      return (
        <>
            <div className="filterHome">
                <div className="filterContainer">
                    

                {/* Lists projects */}
                
                <div className="projects">
                    // THIS IS WHAT I TRIED DOING THE FIRST TIME WHICH DOESN'T WORK
                    {/* {this.state.jsonLength > 0 &&
                        <div className="content">
                            {this.state.projects && this.state.projects.map((project) => (
                                <ProjectDetails key={project._id} project={project}/>
                            ))}
                        </div>
                    }
                    {this.state.jsonLength === 0 &&
                        <div > 
                            No Projects
                        </div>
                    } */}
                    
                    // THIS IS WHAT I TRIED DOING THE SECOND TIME WHICH STILL DOESN'T WORK
                    {this.state.jsonLength > 0 ? this.projectDisplay() : console.log('no projects')}
                    
                    
                </div>
            </div>
        </>
      );
    }
  }
export default FilterBody

This is what I tried doing the first time once something comes from the backend but this didn’t work and just displayed nothing when jsonLength === 0:

{this.state.jsonLength > 0 &&
    <div className="content">
        {this.state.projects && this.state.projects.map((project) => (
            <ProjectDetails key={project._id} project={project}/>
        ))}
    </div>
    }
    {this.state.jsonLength === 0 &&
    <div > 
        No Projects
    </div>
} 

This is what I tried doing the second time but this didn’t work either and when the statement was false it still didn’t show no projects in the console despite what I put:

{this.state.jsonLength > 0 ? this.projectDisplay() : console.log('no projects')}

Does anyone know why my conditional rendering isn’t working?

Advertisement

Answer

setState accepts a single object as the 1st argument & the 2nd optional argument is a callback function. It should be

this.setState({projects: json, jsonLength: json.length})

In my opinion, you can omit jsonLength & use this.state.projects.length instead.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement