Home > Back-end >  How to pull specific data from an array?
How to pull specific data from an array?

Time:11-09

I have created an array that gives a certain ID to each component every time it is added to the array. But now that the component is created, I want to be able to pull the data. Like the boxid or title when needed.

I currently am trying to make the value of <textarea /> in Todobox.jsx the unique boxid. But it does not seem to print a value.

Here is my code:

ElementContext.js:

import React, { createContext, useState } from 'react';
import Todobox from './components/Todobox';

export const ElementContext = createContext();

export const ElementContextProvider = ({children}) => {
    const [elements, setElements] = useState([]);
    const [elementId, setElementId] = useState(0);
    const [refDict, setRefDict] = useState({});

    const newElementId = (elements) =>{
        setElementId(elementId   1);
        console.log(elementId)
    }

    const newElement = () => {
        newElementId();
        if (!refDict[elementId]) { //so if nothing in "refDict" that means the elementId is unique
          setElements(prev => [...prev, { title: 'Placeholder', boxid: elementId }]);
          setRefDict((prev) => ({...prev, [elementId]: true}));
        }
        console.log(elements);
      };

    const value = {
        elements,
        setElements,
        newElement,
        elementId
    };

    return(
        <ElementContext.Provider value={value}>
            {children}
        </ElementContext.Provider>
    )
};

HomePage.jsx:

import react from 'react';
import { useEffect, useContext } from 'react';
import '../App.css';
import Todobox from './Todobox';
import { ElementContext } from '../ElementContext';

export default function HomePage(){
    const { elements, setElements, newElement, elementId } = useContext(ElementContext);

    return(
        <div className='page-container'>
        <div className='header'>
          <a className='header-title'>Trello Clone!</a>
          <a className='header-button' onClick={newElement}>Create a list</a>
        </div>
      <div className='element-field'>
        
         {elements.map((elements, elementId) => <Todobox key={elementId} />)}
        
      </div>
    </div>
    )
}

Todobox.jsx:

import React from 'react';
import Item from './Item';
import { useContext } from 'react';
import '../App.css';
import { ElementContext } from '../ElementContext';

export default function Todobox(){
    const { elements, setElements, newElement, elementId } = useContext(ElementContext);
    return(
        <div className='element-box'>
            <a className='element-title'>PlaceHolder</a>
            <Item />
            <textarea 
            className='element-input' 
            type='text' 
            placeholder={elements.boxid}
            />
        </div>
    )
}

I am pretty new to react and such so any help is appreciated!

CodePudding user response:

The elements array in state (and context) is an array of objects, and those objects have a boxid property. To use it, you need to reference or pass down that property when iterating over the elements. So your starting point would be to change this line:

elements.map((elements, elementId) => <Todobox key={elementId} />)

I'd change Todobox so that it doesn't use context at all, and is instead passed down all values it needs to render from the parent, including the boxid.

Other issues:

  • The .map callback parameter is not an array - it's a single object, so it should probably be called element, not elements, to avoid confusion
  • Keys should usually not be the index of the element in the array. Use a more unique identifier, such as the boxid, which will never change for a particular object. (In your current implementation, the elementId in the .map callback may not reflect the actual boxid of the object being iterated over, if you ever remove an item from the middle of the state array.)
elements.map((element) => <Todobox key={element.boxid} boxid={element.boxid} />)
export default function Todobox({ boxid }){
    return(
        <div className='element-box'>
            <a className='element-title'>PlaceHolder</a>
            <Item />
            <textarea 
            className='element-input' 
            type='text' 
            placeholder={boxid}
            />
        </div>
    )
}
  • Related