6

Lets say I have a list in react jsx

<ul>
    <li>stuff</>
    <li>stuff</>
    <li>stuff</>
    <li>stuff</>
    <li>stuff</>
</ul>

How would I select one of the list items? I don't mean on the client side in the case I could just attach a click listener. But lets say I get a message from the server that I need to do something with the third item on the list. What I have been doing until now is setting the list items as state and then for example if I want to delete the middle item I simply update the state with a new list that doesn't include the middle item. The problem with this is that if the list is huge it seems bad practice to be constantly deleting and recreating a huge list, or perhaps maybe I don't want to delete/add any list items but do something like add some text or animation to a specific list item.

7
  • 1
    you don't have code to show ? Because I think I didn't understand well Commented Nov 30, 2020 at 21:26
  • 1
    It's always a good idea to attach the "view/component" to state if the rendering will depend upon state. So, yes it's a good idea to create and mantain the list in state, while you re-render upon state changes. If the list is huge, you can use some pagination for that list, or some react component that renders incrementally on scroll down. Commented Nov 30, 2020 at 21:36
  • you could attach the event listener to ul, and to set ref to ul, then to capture the event, get its id and to filter array of li, so firstly create an array of li and render them like this {listItems.map((text, i)=> <li key={i}>{text}</li>)}, when the click happens you just filter the list array, so set it as state Commented Nov 30, 2020 at 21:38
  • 1
    Would be nice to see some more context of course, but let me see if I understand you correctly. You have the UL element rendered on a page. Somehow you want to query a remote server to see if it wants something done with any individual LI inside the UL right? And your question is how to accomplish it? Is that the idea? Commented Dec 3, 2020 at 0:32
  • "The problem with this is that if the list is huge it seems bad practice to be constantly deleting and recreating a huge list". It sounds like you need to render this as an array of elements, and use keys. Then the whole set of DOM elements won't be recreated when you just want to insert or remove one. Commented Dec 3, 2020 at 22:31

3 Answers 3

1
+50

Use an array of objects

You want to modify a large amount of data constantly without replicating it. You also want additional behavior on some of the item, but not all of them. You are probably using an array right now, which would make it difficult to achieve those things.

An array of objects, on the other hand, allows much more flexibility. Where arrays are indexed, objects can have arbitrary IDs and other properties.

For example:

let myObj = [
{
  id: 0,
  text: 'Text from the DB',
  showSpecialTextColor: false,
  showSpecialAnimation: false,
},
{
  id: 1,
  text: 'Another text value.',
  showSpecialTextColor: false,
  showSpecialAnimation: false,
},
{
  id: 2,
  text: 'This text should display with special styling.',
  showSpecialTextColor: true,
  showSpecialAnimation: true,
},
]

Now you can add or delete items into this parent object based on their id, versus their index. This doesn't require the rest of the object to be replicated or changed.

myObj.map(item => {
            if (item.id = 2) {
                delete item
            }
        })

showSpecialTextColor is an arbitrary property that you can create on your object. You can have your rendering component perform a check for this property and change styling or logic based on its value.

If your database returns your data in an array format, you can always convert it to an object when you first retrieve it from the DB.

Sign up to request clarification or add additional context in comments.

Comments

0

You have to have state for this case. DOM updates for your list are dependent on the data behind that list. As a general rule you can use pagination/infinite scrolls, however I see two concerns in your question:

The problem with this is that if the list is huge it seems bad practice to be constantly deleting and recreating a huge list

You should not "recreate" it as often as it seems. Immutable data libraries such as immutable.js can help you avoid recreating your huge lists.

perhaps maybe I don't want to delete/add any list items but do something like add some text or animation to a specific list item.

This is ambiguous to me. I can only guess you're trying to avoid searching the giant list on every trigger such as click or server message. If so, then it really depends on your particular implementation. Perhaps a simple trick will suffice:

//pre-populated object to map a primary data type to your item.
//i suggest you restructure your data shape so you don't have to introduce extra work
const maps = {
  //id: data item
}

const handleClick = (id) => {
  //here you can avoid a search of entire list
  const item = maps[id]
  //update item as you wish
}

<ul>
  {items.map(item => 
    <li>
      <button onClick={() => handleClick(item.id)}>Click Me</button>
    </li>
  }
</ul>

Comments

0

You can use library like react-virtualized to manage your list. This will improve your performance in many ways like it will show only those items which are visible in your viewport and rest it will remove from the DOM.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.