Home > Back-end >  How to reference an object name in React with the key?
How to reference an object name in React with the key?

Time:01-29

So I'm coding a budget app right now, and I'm using a drop-down menu in a certain part of the app.

<Dropdown>
   <Dropdown.Button color="secondary">{selectedValue}</Dropdown.Button>
   <Dropdown.Menu ref={budgetIDRef} selectionMode="single" selectedKeys={selected} onSelectionChange={setSelected} aria-label="Multiple selection actions">
      
   {budgets.map(budget => (
      <Dropdown.Item key={budget.id}>{budget.name}</Dropdown.Item>
   ))}

   </Dropdown.Menu>
</Dropdown>

The .map() here serves to introduce a dropdown selection option for each budget item key, using the name to display the name. This all works, however the {selectedValue} for the Button displays the key, not the name (as it's derived from {selected} which assigns the selected key). So my question is, how can I extract the name of my object using the key?

I tried using an if statement within .map(), but it didn't work properly and when it did work it was displaying all the names of my objects in local storage one after the other.

CodePudding user response:

One option is to find the selected budget based on the selected value:

const selectedBudget = budgets.find(budget => budget.id === selectedValue);

return (
  <Dropdown>
     <Dropdown.Button color="secondary">{selectedBudget?.name}</Dropdown.Button>
     <Dropdown.Menu ref={budgetIDRef} selectionMode="single" selectedKeys={selected} onSelectionChange={setSelected} aria-label="Multiple selection actions">
        
     {budgets.map(budget => (
        <Dropdown.Item key={budget.id}>{budget.name}</Dropdown.Item>
     ))}
  
     </Dropdown.Menu>
  </Dropdown>
)

You may want to wrap this calculation in a useMemo so it only runs when the selected budget changes. For example:

const selectedBudget = useMemo(() => {
  return budgets.find(budget => budget.id === selectedValue)
}, [budgets, selectedValue]);

CodePudding user response:

One way to do it would be changing the the function that you call on onSelectionChange to a custom function that would receive the value of key (I'm assuming this is the only value that you get to work with since I don't know wich lib you're using). This custom function would use this key value, wich is the budget.id, to filter the bugdets array and update the selectedValue state with the name and the id of the selected budget. Then you would call selectedValue.name inside the <Dropdown.Button>. The code could be something like this:

const [selectedValue, setSelected] = useState({});

const updateSelectedValue = (budgetId) => {

   const selectedBuget = budgets.filter(budget => budget.id === budgetId);
   
   setSelected({
      name: selectedBuget.name,
      id: selectedBuget.id
   });
}

return (

<Dropdown>
   <Dropdown.Button color="secondary">{selectedValue.name}</Dropdown.Button>
   <Dropdown.Menu ref={budgetIDRef} selectionMode="single" selectedKeys={selected} onSelectionChange={updateSelectedValue} aria-label="Multiple selection actions">
      
   {budgets.map(budget => (
      <Dropdown.Item key={budget.id}>{budget.name}</Dropdown.Item>
   ))}

   </Dropdown.Menu>
</Dropdown>

);

See, the code I provided is not optimized and don't do validity checks. So if you decide on moving forward with my suggestion, add the necessary validations to see if the objects and properties you're trying to access are not undefined.

  • Related