简体   繁体   中英

Hot to get object key from an array of objects

I have this array of objects called name[] (for example), as shown in the console log I have printed below.

With each user who logs in, his name will be added to the option with name: key, and another object with all data is added. (This is just how I've got up to now to work, there may be cleaner ways but for now I'm close to getting what I need so no need rework that imo).

0:
id: "users"
name: {Dick: true, Harry: true, Tom: true}
__proto__: Object
1:
id: "users"
name: {Dick: true, Harry: true, Tom: true}
__proto__: Object
2:
id: "users"
name: {Dick: true, Harry: true, Tom: true}
__proto__: Object

I am aiming to list the different names in a React component. When I try to map through the array as it is, I get "Uncaught Error: Objects are not valid as a React child" - because of course the array/objects within are not in the format I need.

I need to map over an array of the names once to add a list to the browser, but for now the names are in an object which is the second value of an oject within an array...

I guess I need to use just one of the objects in the original array (as they are all the same), ignore the 'id' key, then map through the object that contains the different names.

This is a little complex for me, separating/reaching the targeted object from within the other data is tricky.

If you have any ideas on the how to do it, I am open to to suggestions.

Thank you. Regarding how I am trying to return the data to the browser, please see below my current attempt that gives the error mentioned above.

 return <div className='container'>

      {/* title */}
      <div className='titleDiv'>
        <h1>React Message App</h1>
        <p className='usersLoggedIn'>Logged in: </p>
        {
          names.map(item => {
            return (
              <p className='usersLoggedIn'>
                {(item.name === this.state.name ? ' ' : item.name)}
              </p>
            )
          })
        }
      </div>
          names.map(item => {
            return (
              <p className='usersLoggedIn'>
                {(item.name === this.state.name ? ' ' : item.name)}
              </p>
            )
          })

You're returning item.name nested inside your p tag, which is an object. I'm editing my answer to achieve what you explained you wanted:

          names.map((item,i) => {
            return (
              <p className='usersLoggedIn'>
                {(item.name === this.state.name ? ' ' : Object.keys(item.name)[i])}
              </p>
            )
          })

This assumes your array, and your object have the same number of elements, which is what I understood from your object structure. I still have to warn you that this is extremely convoluted, and you might want to look into re-structuring your object instead, or at least your map function:

          Object.keys(names[0].name).map(item => {
            return (
              <p className='usersLoggedIn'>
                {item}
              </p>
            )
          })

In the render method when you are iterating through the names array, item.name consists of the inner object like {Dick: true, Harry: true, Tom: true} which is rendered inside a <p> tag. This is invalid because an object cannot be a children node of the p tag let alone any dom element.

If you want to render all of the inner name for each object in the name array, you will have to get the necessary data from the inner object {Dick: true, Harry: true, Tom: true} and then render it.

example

 return <div className='container'>

  {/* title */}
  <div className='titleDiv'>
    <h1>React Message App</h1>
    <p className='usersLoggedIn'>Logged in: </p>
    {
      names.map(item => {
        return (
          <p className='usersLoggedIn'>
            { // parse the inner object to get all the name keys
               Object.keys(item.name).map((innerItem) => <span>{innerItem}&nbsp;</span>)
            }
          </p>
        )
      })
    }
  </div>

Is it what you need?

编辑 quirky-gagarin-uq1n3

What it does:

  • Filters all the names (keys in name property of each object in the array)
  • Display names that is not equal to the state.name
const data = [
  {
    id: "users",
    name: { Dick: true, Harry: true, Tom: true }
  },
  {
    id: "users",
    name: { Dick: true, Harry: true, Tom: true }
  },
  {
    id: "users",
    name: { Dick: true, Harry: true, Tom: true }
  }
];

const getAllUsers = () => {
  return data.reduce((arr, obj) => {
    const names = Object.keys(obj.name);
    const newNames = names.filter(name => {
      return !arr.includes(name);
    });
    return arr.concat(newNames);
  }, []);
};

class App extends React.Component {
  state = {
    name: "Harry"
  };

  render() {
    return (
      <div>
        <h1>Header</h1>
        {getAllUsers().map(user => (
          <p>{user === this.state.name ? "" : user}</p>
        ))}
      </div>
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM