0

I am trying to write multiple components in a single .jsx file. But for some reason it doesn't work in React 18. It was working fine in the previous Versions. But when i create a separate .jsx file for the component and import it, it works. Following is an example code:

const ChannelListContainer = () => {

  return (
    <>
      <Sidebar logout={logout} />
      <div className="channel-list__list__wrapper">
        <CompanyHeader />
        <ChannelSearch />
        <ChannelList
          filters={{}}
          channelRenderFilterFn={() => {}}
          List={(listProps) => <TeamChannelList {...listProps} type="team" />}
          Preview={(previewProps) => (
            <TeamChannelPreview {...previewProps} type="team" />
          )}
        />
        <ChannelList
          filters={{}}
          channelRenderFilterFn={() => {}}
          List={(listProps) => (
            <TeamChannelList {...listProps} type="messaging" />
          )}
          Preview={(previewProps) => (
            <TeamChannelPreview {...previewProps} type="messaging" />
          )}
        />
      </div>
    </>
  );
};

The sidebar component imported in the above code was first meant to be in the same file. But i had to create the Sidebar component separately to use it. How can i write two components in the same .jsx file and use them in React 18?

Mushood Hanif
  • 501
  • 1
  • 5
  • 17
  • Do you get any error messages? – GROVER. Apr 10 '22 at 22:08
  • @GROVER. i got one error message regarding my outdated index.js code. But when i corrected that according to the new documentation, i get no error messages, the page just goes blank. – Mushood Hanif Apr 10 '22 at 22:10
  • 1
    Same way as in previous versions of React, so there's something else at play. Check browser and console logs and make sure it's actually compilable. Then divide-and-conquer; start commenting out chunks to see where things have gone awry. – Dave Newton Apr 10 '22 at 22:24
  • As @DaveNewton said, the best way to go about this when there's no error output is to comment out components until you find the offending one. – GROVER. Apr 10 '22 at 22:51
  • @DaveNewton i have noticed that unlike in React 17, if you write multiple components within the same file, then in order to use the child component in the main component, you'll have to add the `return()` around the `div` element you are returning. I will have to try this and reply back. – Mushood Hanif Apr 10 '22 at 22:58
  • @MushoodHanif I'm not sure what that means; are you saying that < 18 if you wrote `return <>

    foo

    bar

    >` it works and now it doesn't? That would be an inexplicable, breaking change to the JSX processor.
    – Dave Newton Apr 10 '22 at 23:04
  • @MushoodHanif Indeed, local testing indicates there are no changes to the JSX processor. My best guess is that you had a `return `, thus returning `undefined`, which is no longer a warning in R18. – Dave Newton Apr 10 '22 at 23:08
  • @DaveNewton I mean that < 18 it didn't matter if I wrote `return()` or not, the component always rendered. But in 18, if `return()` is not written, then the component won't render. I'll add an answer to my question. Hopefully it will allow you to understand the issue better. – Mushood Hanif Apr 11 '22 at 08:47

1 Answers1

-2

The issue was that it is now mandatory to add the return() around the div inside the component you want to render or else it won't render. This wasn't the case in the previous React versions. I might be wrong but this is currently the case for me. Note that both these components are in a single .jsx file.

const Sidebar = ({ logout }) => {
  return ( // without this, the component won't render. This isn't the case in < 18 React.
    <div className="channel-list__sidebar">
      <div className="channel-list__sidebar__icon1">
        <div className="icon1__inner">
          <img src={HospitalIcon} alt="Hospital" width="30" />
        </div>
      </div>
      <div className="channel-list__sidebar__icon2">
        <div className="icon1__inner" onClick={logout}>
          <img src={LogoutIcon} alt="Logout" width="30" />
        </div>
      </div>
    </div>
  );
};

const ChannelListContainer = () => {
  return (
    <>
      <Sidebar logout={logout} />
      <div className="channel-list__list__wrapper">
        <CompanyHeader />
        <ChannelSearch />
        <ChannelList
          filters={{}}
          channelRenderFilterFn={() => {}}
          List={(listProps) => <TeamChannelList {...listProps} type="team" />}
          Preview={(previewProps) => (
            <TeamChannelPreview {...previewProps} type="team" />
          )}
        />
        <ChannelList
          filters={{}}
          channelRenderFilterFn={() => {}}
          List={(listProps) => (
            <TeamChannelList {...listProps} type="messaging" />
          )}
          Preview={(previewProps) => (
            <TeamChannelPreview {...previewProps} type="messaging" />
          )}
        />
      </div>
    </>
  );
};
Mushood Hanif
  • 501
  • 1
  • 5
  • 17
  • 1
    "This wasn't the case in the previous React versions." — Yes, it was. – Quentin Apr 11 '22 at 09:04
  • In the first example, if you have return followed by a newline (no parentheses) it will return "undefined", because that's how JavaScript works--it's a well-known JS "gotcha". There's been no change in this behavior. – Dave Newton Apr 11 '22 at 13:31
  • @DaveNewton this i understand, i am saying that the absence of `return()` itself is the problem in React 18 and was not a problem in < 18. But as @Quentin pointed out, maybe i was mistaken. Anyway, i learned something, so thanks. – Mushood Hanif Apr 12 '22 at 15:52
  • @MushoodHanif Nothing about this has changed--it's either what I mentioned first, or a difference between curly-braces/no-curly-braces. Since you've never shown what you say works in React < 18 but breaks in React 18 all we can do is guess--but nothing at all indicates it has anything to do w/ the React version. A change like you're claiming would potentially break every single React app and run counter to JavaScript itself. – Dave Newton Apr 12 '22 at 15:59