Home > front end >  React complaining about key-less children when all children have keys
React complaining about key-less children when all children have keys

Time:11-02

As the title says, React is throwing an error about children in a list having unique keys and I have no clue why. I am building a Twitch chat clone, and this is happening with my emote picker, where every emote available for your use is listed as a clickable icon. Every map function I use spits out components with keys. I even went through every single component and added a unique key whether it really needed it or not, and I am still getting the warning. Clicking the first few trace links leads to nothing useful.

I know my code might not be super clear, and I apologize for this, but any help would be appreciated.

Here is the return statement for the affected component:

return (
    <Popover placement="top">
      <PopoverTrigger>
        <Button disabled={!loggedIn || !connected}>
          {
            <Box
              as="img"
              width={[12, 10, 10, 8]}
              alt="Emote Picker"
              // src="https://static-cdn.jtvnw.net/emoticons/v2/305954156/static/light/3.0" // PogChamp
              src="https://static-cdn.jtvnw.net/emoticons/v2/307445021/static/light/3.0" // Orangie
              title="Emote Picker"
            />
          }
        </Button>
      </PopoverTrigger>

      <PopoverContent>
        <PopoverArrow />
        <PopoverCloseButton />
        <Flex height={400} overflow="auto" direction="column">
          {showBTTVChannel && (
            <>
              <PopoverHeader>BTTV Channel Emotes</PopoverHeader>
              <PopoverBody>
                <Flex flexWrap="wrap">
                  {bttvEmotes !== null &&
                    // eslint-disable-next-line array-callback-return
                    Object.keys(bttvEmotes).map((key, index) => {
                      if (bttvEmotes[key]['category'] === 'bttv_channel') {
                        return (
                          <ChatEmote
                            key={index}
                            name={key}
                            src={
                              bttvEmotes[key][userOptions.emoteQuality   'x']
                            }
                            height={8}
                            margin={1.5}
                            onClick={() => onClickHandler(key)}
                          />
                        );
                      }
                    })}
                </Flex>
              </PopoverBody>
            </>
          )}

          {showFFZChannel && (
            <>
              <PopoverHeader>FFZ Channel Emotes</PopoverHeader>
              <PopoverBody>
                <Flex flexWrap="wrap">
                  {bttvEmotes !== null &&
                    // eslint-disable-next-line array-callback-return
                    Object.keys(bttvEmotes).map((key, index) => {
                      if (bttvEmotes[key]['category'] === 'ffz_channel') {
                        return (
                          <ChatEmote
                            key={index}
                            name={key}
                            src={
                              bttvEmotes[key][userOptions.emoteQuality   'x']
                            }
                            height={8}
                            margin={1.5}
                            onClick={() => onClickHandler(key)}
                          />
                        );
                      }
                    })}
                </Flex>
              </PopoverBody>
            </>
          )}

          {showBTTVShared && (
            <>
              <PopoverHeader>BTTV Shared Emotes</PopoverHeader>
              <PopoverBody>
                <Flex flexWrap="wrap">
                  {bttvEmotes !== null &&
                    // eslint-disable-next-line array-callback-return
                    Object.keys(bttvEmotes).map((key, index) => {
                      if (bttvEmotes[key]['category'] === 'bttv_shared') {
                        return (
                          <ChatEmote
                            key={index}
                            name={key}
                            src={
                              bttvEmotes[key][userOptions.emoteQuality   'x']
                            }
                            height={8}
                            margin={1.5}
                            onClick={() => onClickHandler(key)}
                          />
                        );
                      }
                    })}
                </Flex>
              </PopoverBody>
            </>
          )}

          {showEmotes &&
            // eslint-disable-next-line array-callback-return
            Object.keys(emoteSets.current).map(key => {
              if (key !== 'Twitch Global') {
                return (
                  <>
                    <PopoverHeader>{key}</PopoverHeader>
                    <PopoverBody>
                      <Flex flexWrap="wrap">
                        {emoteSets.current !== null &&
                          Object.keys(emoteSets.current[key]['emotes']).map(
                            (key, index) => {
                              return (
                                <ChatEmote
                                  key={index}
                                  name={key}
                                  src={
                                    userEmotes[key][
                                      userOptions.emoteQuality   'x'
                                    ]
                                  }
                                  height={8}
                                  margin={1.5}
                                  onClick={() => onClickHandler(key)}
                                />
                              );
                            }
                          )}
                      </Flex>
                    </PopoverBody>
                  </>
                );
              }
            })}

          <PopoverHeader>BTTV Global Emotes</PopoverHeader>
          <PopoverBody>
            <Flex flexWrap="wrap">
              {bttvEmotes !== null &&
                // eslint-disable-next-line array-callback-return
                Object.keys(bttvEmotes).map((key, index) => {
                  if (bttvEmotes[key]['category'] === 'bttv_global') {
                    return (
                      <ChatEmote
                        key={index}
                        name={key}
                        src={bttvEmotes[key][userOptions.emoteQuality   'x']}
                        height={8}
                        margin={1.5}
                        onClick={() => onClickHandler(key)}
                      />
                    );
                  }
                })}
            </Flex>
          </PopoverBody>

          {showEmotes && (
            <>
              <PopoverHeader>Twitch Global</PopoverHeader>
              <PopoverBody>
                <Flex flexWrap="wrap">
                  {emoteSets.current !== null &&
                    Object.keys(
                      emoteSets.current['Twitch Global']['emotes']
                    ).map((key, index) => {
                      return (
                        <ChatEmote
                          key={index}
                          name={key}
                          src={userEmotes[key][userOptions.emoteQuality   'x']}
                          height={8}
                          margin={1.5}
                          onClick={() => onClickHandler(key)}
                        />
                      );
                    })}
                </Flex>
              </PopoverBody>
            </>
          )}
        </Flex>
      </PopoverContent>
    </Popover>
  );

CodePudding user response:

key must added to the parent wrapper component which you're returning key is missing -->

{showEmotes &&
            // eslint-disable-next-line array-callback-return
           //map second argument return the index of current element
            Object.keys(emoteSets.current).map((key,i) => {
              if (key !== 'Twitch Global') {
                return (
                //missing key
                  <div key={i}>
                    <PopoverHeader>{key}</PopoverHeader>
                    <PopoverBody>
                      <Flex flexWrap="wrap">
                        {emoteSets.current !== null &&
                          Object.keys(emoteSets.current[key]['emotes']).map(
                            (key, index) => {
                              return (
                                <ChatEmote
                                  key={index}
                                  name={key}
                                  src={
                                    userEmotes[key][
                                      userOptions.emoteQuality   'x'
                                    ]
                                  }
                                  height={8}
                                  margin={1.5}
                                  onClick={() => onClickHandler(key)}
                                />
                              );
                            }
                          )}
                      </Flex>
                    </PopoverBody>
                  </>

does this solve issue ?

  • Related