DEV Community

Cover image for Component Trees and the Benefit of Mind Maps
lakota
lakota

Posted on

Component Trees and the Benefit of Mind Maps

Taking Notes. Organization. Do you recall the last time you made a list? What about the last time you had to take notes on something? When was the last time you had to make notes from which you could study? Perhaps you're taking notes now. What is the format of these notes? For the longest time, I took notes like the vast majority of people. I had a notebook, and within it I organized my thoughts line by line, a veritable, verticle column of thoughts with a wonderful array of Headers and footers, bulletpoints and indentations, commas and colons to try my best to denote difference, characterize and categorize in order to order my thoughts.
And then, perhaps a year ago and for the first time in my life, I was thrust abruptly into a situation in which it was truly important I learn and memorize something thoroughly and quickly. Something so intensely complex that a lifetime, nay many lifetimes could be spent in the adept and rigorous study of its facets: Magic The Gathering.

Image description
In a panic, but determined to beat my brother and his fiance at their own game, I grabbed a pen and paper and with as much dexterity as I could muster, I scrambled down notes of what my companions were telling me of the rules of the game. Quickly, out of necessity, ordered list turned into paragraph here, to note there, to line pointing here or there. Concepts left the great verticle column of order that had defined notation for a lifetime, wandering into a web of connected thoughts, distinct across the page in space but connected by branching paths. It wasn't a list of information anymore. It was a map. Complete with doodles and everything. And while it at first seemed a mess, quickly I came to realize how much more beneficial to me it was to have my concepts, the components of my thoughts, in distinct places, with connective throughlines to work with. What I had accidentally created was a mind map.

Image description
By CS Odessa - http://www.conceptdraw.com/solution-park/resource/images/solutions/bubble-diagrams/Spray_diagram_Student_%20learning_charasterictics.png, CC BY 4.0, https://commons.wikimedia.org/w/index.php?curid=42804280

A mind map is simply a means of organizing information into a hierarchy. It typically relies on concepts visually branching from one another, connecting on ways that denote that they are related, as well as their order of importance. As I continue further into my journey of learning to code, I have found that there are many visual learners like myself who benefit from the use of mind maps, and struggled with finding information and intuiting the relationship between elements of code in vanilla javascript, html, and css. Nesting often simply just doesn't cut it as far as visually denoting the relationships between functions, objects and the like:

    function raceDetails(raceInQuestion) {
    //    const proficienciesArray = []
    //    const bookProfs =document.createElement("P")
    //    const rightPage = document.querySelector("#right-page")
    //    rightPage.innerhtml = ""

    //    const bookLanguages =document.createElement("P")
    //    let languageString = ``


        current = raceInQuestion
        const raceName = document.querySelector("#form-race")
        let primaryAbilityField = document.querySelector('#primary-ability');
        let secondaryAbilityField = document.querySelector("#secondary-ability")
        let languages = document.querySelector('#languages');
        languages.innerHTML = ""
        const optionalProfs = document.querySelector(`#optional-profs`)
        const selectableProfs = document.querySelector(`#selectable-profs`)
        selectableProfs.innerHTML = ""
        const optionalAbility = document.querySelector(`#optional-ability`)
        const halfElfAbility = document.querySelector(`#half-elf-ability`)
        const primaryAbility = raceInQuestion.ability_bonuses[0].ability_score.index
        totalProfs = 0
        //confirms that racial proficiencies exist before populating that section of the form
        // let abilityString = `${primaryAbility}`
        // const bookAbilities =document.createElement("P")
        // const bookNames = document.createElement("h3")
        // bookNames.textContent = `${raceInQuestion.name}`

        if (raceInQuestion.starting_proficiencies[0]) {
            raceInQuestion.starting_proficiencies.forEach((proficiency) => {
                const newChoice = document.createElement("tr")
                const defaultProf = document.createElement("td")
                const choiceSelect = document.createElement("td")
                // proficienciesArray.push(proficiency)

                defaultProf.innerHTML = `${proficiency.name}`

                choiceSelect.innerHTML = `
        <input id="prof-${totalProfs}" type="text value="" placeholder="Your Choice Here"></input>
        `
                totalProfs++
                newChoice.append(defaultProf)
                newChoice.append(choiceSelect)
                selectableProfs.append(newChoice)

                optionalProfs.hidden = false
            })
        } else {
            optionalProfs.hidden = true
        }
            // bookProfs.textContent= proficienciesArray
            // rightPage.append(bookProfs)
        //confirms that the race has a secondary (or teritiary) ability bonus before populating the form with it
        if (raceInQuestion.ability_bonuses[1]) {
            // abilityString = abilityString + " " + raceInQuestion.ability_bonuses[1].ability_score.index
            secondaryAbilityField.value = raceInQuestion.ability_bonuses[1].ability_score.index
            secondaryAbilityField.options[`${raceInQuestion.ability_bonuses[1].ability_score.index}`].innerText = raceInQuestion.ability_bonuses[1].ability_score.index.toUpperCase()
            optionalAbility.hidden = false
            halfElfAbility.hidden = true
        } else if (raceInQuestion.index === "half-elf") {
            halfElfAbility.hidden = false
            optionalAbility.hidden = false
        } else {
            optionalAbility.hidden = true
            halfElfAbility.hidden = true

        }

        // all races have languages by default, so this will generate a section on the form
        // to customize the language, setting the initial values to the racial defaults
        totalLangs = 0
        raceInQuestion.languages.forEach((language) => {
            // languageString = languageString + " " + `${language}`
            const newRow = document.createElement("tr")
            const newLanguage = document.createElement("td")



            newLanguage.innerHTML = `
        <select name="language-${totalLangs}" class="language-${totalLangs}">
            <option value="abyssal">Abyssal</option>
            <option value="celestial">Celestial</option>
            <option value="common">Common</option>
            <option value="deep-speech">Deep Speech</option>
            <option value="draconic">Draconic</option>
            <option value="dwarvish">Dwarvish</option>
            <option value="elvish">Elvish</option>
            <option value="giant">Giant</option>
            <option value="gnomish">Gnomish</option>
            <option value="goblin">Goblin</option>
            <option value="halfling">Halfling</option>
            <option value="infernal">Infernal</option>
            <option value="orc">Orc</option>
            <option value="primordial">Primordial</option>
            <option value="sylvan">Sylvan</option>
            <option value="undercommon">Undercommon</option>
        </select>
        `
            newRow.append(newLanguage)
            languages.append(newRow)
            document.querySelector(`.language-${totalLangs}`).value = language.index
            totalLangs++
        })



        raceName.value = raceInQuestion.name

        primaryAbilityField.value = primaryAbility
        primaryAbilityField.options[`${primaryAbility}`].innerText = primaryAbility.toUpperCase()

        // bookLanguages.textContent = languageString
        // bookAbilities.textContent = abilityString
        // const bookRace = document.createElement("P")
        // bookRace.textContent = `${raceInQuestion.name}`
        // rightPage.append(bookRace)
        // rightPage.append(bookProfs)
        // rightPage.append(bookAbilities)
        // rightPage.append(bookLanguages)
    }
Enter fullscreen mode Exit fullscreen mode

I don't know about you, but this is very difficult for me to follow. That is why I prefer the use of React.js Component Trees.

Image description
Looking at this image, we can see that instead of having all of our javascript bunched together in a single file, with React we are able to take the individual elements that compose our javascript and separate them out into distinct files known as components that are listed to the left.
We are then able to link these distinct components of our code through the use of imports and exports. Virtually all of our components are given the ability to export their information, typically through the use of a bit of code tapped out at the bottom of the page, such as in our component BlogCard from the top of our components list in the picture above:

import React from "react";

function BlogCard({blogs}) {
  return (
    <li className="card">
      <div>{blogs.title}</div>
      <div>{blogs.author}</div>
      <div>{blogs.date}</div>
      <div>{blogs.video}</div>
      <div>{blogs.divider}</div>
    </li>
  );
}

export default BlogCard;
Enter fullscreen mode Exit fullscreen mode

Here, we are exporting the function BlogCard, which means that if it is imported, or called by another component, that component now has access to the results of that function. Here, the function BlogCard returns a list of values from an array in our dbjson. However, were we to import this function into BlogList, like so:

import React from "react";
import BlogCard from "./BlogCard";
import PostCard from "./PostCard";

function BlogList({blogs,posts}){
    const mappedPosts = posts.map((posts)=>{
        return <PostCard key={posts.id} posts={posts} />
    })    
    const mappedBlogs = blogs.map((blogs)=>{
        return <BlogCard key={blogs.id} blogs={blogs} />
    })

    return (
        <ul className="cards">
            {mappedPosts}
            {mappedBlogs}
        </ul>
    );
}

export default BlogList;
Enter fullscreen mode Exit fullscreen mode

We can now use that array of values from BlogCard with the function present in BlogList. Here, BlogList is being used to map through the entirety of the "blogs" portion of our backend to return an array of BlogCard return functions, one for each object in our blogs array.
We can think of this relationship like a branch on our mind map, in which a function that is imported into another function is a further part on the branch of the diagram. We can also see here that BlogList imports another function, PostCard, and returns the same thing with that function as BlogCard. We can think of this relationship visually as BlogCard and PostCard being two forks off the main branch, BlogList. For visual learners like me, being able to use this simple import/export system to create a mind map of my code has been extremely helpful and allowed me to create things that would be far too complicated for me with vanilla Javascript:

Image description

Top comments (0)