0

I'm struggling with being able to render html elements in my sidebar dynamically. Currently, this is only set up to receive a list of projects of at least 1 but up to 5, as well as 1-5 subprojects. The HTML is hardcoded, and I was wondering if there is a way to just reuse the same block of HTML for each item in the project list.

import React, { useContext, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { DashboardContext } from '../dashboardContext/DashboardContext'
import './sidebar.css'
import Accordion from 'react-bootstrap/Accordion'
import Card from 'react-bootstrap/Card'
import './homeicon.png'

function Sidebar() {
    const [view, setView] = useContext(DashboardContext)

    var host = "http://localhost:3000/"
    var config = view.configFile
    var itemToFetch = host + config
    const data = view.configInput

    useEffect(() => {
        async function fetchData() {
            const res = await fetch(itemToFetch);
            res
                .json()
                .then(res => setConfigData(res));
        }
        fetchData();
        // eslint-disable-next-line react-hooks/exhaustive-deps,
    }, [view.configFile]); //fetchData when view.configFile changes

    //have to make separate setter functions because otherwise the whole view gets overwritten (i.e., with "undefined")
    const setProject = (name) => {
        setView({ ...view, name: name });
    }

    const setConfigData = (data) => {
        setView({ ...view, configInput: data })

    }

    if (data == null) {
        return (null)
    }

    // NEEDS HELP
    //currently this is only set up to receive project lists of at least 1 but up to 5
    //the number of subprojects can be up to 6 (the compiler doesn't complain about having the expected number of subprojects if it's below that)
    else if (data != null) {
        return (
            <div className="sidebar">
                <Accordion>
                    <Link to='/dashboard'>
                        <img className="home-img" alt="a house" src={require('./homeicon.png')} />
                        <p className="homeTitle" onClick={() => setProject(view.configFile)}>Home</p>
                    </Link>

                    {/* Group 1 */}
                    <Card>
                        <Accordion.Toggle as={Card.Header} eventKey="0">
                            <p>{data[0].projectName}</p>
                        </Accordion.Toggle>
                        <Accordion.Collapse eventKey="0">
                            <Card.Body>
                                <Link to='/dashboard'>
                                    <p onClick={() => setProject(data[0].nickname)}>{data[0].projectName} Overall</p>
                                </Link>
                                <Link to='/dashboard'>
                                    <p onClick={() => setProject(data[0].subprojectNicknames[0])}>{data[0].subprojects[0]}</p>
                                </Link>
                                <Link to='/dashboard'>
                                    <p onClick={() => setProject(data[0].subprojectNicknames[1])}>{data[0].subprojects[1]}</p>
                                </Link>
                                <Link to='/dashboard'>
                                    <p onClick={() => setProject(data[0].subprojectNicknames[2])}>{data[0].subprojects[2]}</p>
                                </Link>
                                <Link to='/dashboard'>
                                    <p onClick={() => setProject(data[0].subprojectNicknames[3])}>{data[0].subprojects[3]}</p>
                                </Link>
                                <Link to='/dashboard'>
                                    <p onClick={() => setProject(data[0].subprojectNicknames[4])}>{data[0].subprojects[4]}</p>
                                </Link>
                                <Link to='/dashboard'>
                                    <p onClick={() => setProject(data[0].subprojectNicknames[5])}>{data[0].subprojects[5]}</p>
                                </Link>
                            </Card.Body>
                        </Accordion.Collapse>
                    </Card>

                    {/* Group 2 */}
                    {(data.length >= 2) ? <div>
                        <Card>
                            <Accordion.Toggle as={Card.Header} eventKey="1">
                                <p>{data[1].projectName}</p>
                            </Accordion.Toggle>
                            <Accordion.Collapse eventKey="1">
                                <Card.Body>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[1].nickname)}>{data[1].projectName} Overall</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[1].subprojectNicknames[0])}>{data[1].subprojects[0]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[1].subprojectNicknames[1])}>{data[1].subprojects[1]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[1].subprojectNicknames[2])}>{data[1].subprojects[2]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[1].subprojectNicknames[3])}>{data[1].subprojects[3]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[1].subprojectNicknames[4])}>{data[1].subprojects[4]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[1].subprojectNicknames[5])}>{data[1].subprojects[5]}</p>
                                    </Link>
                                </Card.Body>
                            </Accordion.Collapse>
                        </Card>
                    </div>
                        : ''}


                    {/* Group 3 */}
                    {(data.length >= 3) ? <div>
                        <Card>
                            <Accordion.Toggle as={Card.Header} eventKey="2">
                                <p>{data[2].projectName}</p>
                            </Accordion.Toggle>
                            <Accordion.Collapse eventKey="2">
                                <Card.Body>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[2].nickname)}>{data[2].projectName} Overall</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[2].subprojectNicknames[0])}>{data[2].subprojects[0]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[2].subprojectNicknames[1])}>{data[2].subprojects[1]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[2].subprojectNicknames[2])}>{data[2].subprojects[2]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[2].subprojectNicknames[3])}>{data[2].subprojects[3]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[2].subprojectNicknames[4])}>{data[2].subprojects[4]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[2].subprojectNicknames[5])}>{data[2].subprojects[5]}</p>
                                    </Link>
                                </Card.Body>
                            </Accordion.Collapse>
                        </Card>
                    </div>
                        : ''}


                    {/* Group 4 */}
                    {(data.length >= 4) ? <div>
                        <Card>
                            <Accordion.Toggle as={Card.Header} eventKey="3">
                                <p>{data[3].projectName}</p>
                            </Accordion.Toggle>
                            <Accordion.Collapse eventKey="3">
                                <Card.Body>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[3].nickname)}>{data[3].projectName} Overall</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[3].subprojectNicknames[0])}>{data[3].subprojects[0]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[3].subprojectNicknames[1])}>{data[3].subprojects[1]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[3].subprojectNicknames[2])}>{data[3].subprojects[2]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[3].subprojectNicknames[3])}>{data[3].subprojects[3]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[3].subprojectNicknames[4])}>{data[3].subprojects[4]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[3].subprojectNicknames[5])}>{data[3].subprojects[5]}</p>
                                    </Link>
                                </Card.Body>
                            </Accordion.Collapse>
                        </Card>
                    </div>
                        : ''}


                    {/* Group 5 */}
                    {(data.length >= 5) ? <div>
                        <Card>
                            <Accordion.Toggle as={Card.Header} eventKey="4">
                                <p>{data[4].projectName}</p>
                            </Accordion.Toggle>
                            <Accordion.Collapse eventKey="4">
                                <Card.Body>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[4].nickname)}>{data[4].projectName} Overall</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[4].subprojectNicknames[0])}>{data[4].subprojects[0]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[4].subprojectNicknames[1])}>{data[4].subprojects[1]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[4].subprojectNicknames[2])}>{data[4].subprojects[2]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[4].subprojectNicknames[3])}>{data[4].subprojects[3]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[4].subprojectNicknames[4])}>{data[4].subprojects[4]}</p>
                                    </Link>
                                    <Link to='/dashboard'>
                                        <p onClick={() => setProject(data[4].subprojectNicknames[5])}>{data[4].subprojects[5]}</p>
                                    </Link>
                                </Card.Body>
                            </Accordion.Collapse>
                        </Card>
                    </div>
                        : ''}
                </Accordion>
            </div>
        )
    }
}

export default Sidebar

Any help appreciated!

  • Does this answer your question? [Render dynamic html in react js](https://stackoverflow.com/questions/47858660/render-dynamic-html-in-react-js) – ravibagul91 Feb 26 '20 at 03:49
  • Also check [this](https://stackoverflow.com/questions/49405679/dynamically-create-components-in-react) – ravibagul91 Feb 26 '20 at 03:50
  • Create an array of data that I guess you have already as data. Loop over it and create an element that you wanted to repeat for every data you have. If you need relevant example, let me know. – Juhil Somaiya Feb 26 '20 at 03:52

0 Answers0