简体   繁体   中英

REACT rendering array from the redux state on the UI

Here's a head-banging question. I've had this component of my app complete for a while, I decided to make a small: seemingly insignificant refactor that's causing something odd to break:

return (
  <div>
    {
      status === "Open" ? ( // REMOVED THIS
        <div style={{ color: "lightgrey" }}>
          <h1 className="text-center">
            {title} <span style={{ fontSize: "0.5em" }}>by {hostedBy}</span>
          </h1>

          <h3>
            {" "}
            <TournamentDescription key={_id} title={title} />{" "}
          </h3>
          <br />

          <p
            className="text-center"
            style={{ color: "#56A8CBFF", fontSize: "2em" }}
          >
            ~ {status} for registration ~
          </p>

          <h4 className="text-left mt-5">
            {participants.length === 1
              ? `${participants.length} Registered Fighter`
              : `${participants.length} Registered Fighters`}
          </h4>

          <ul>
            {participants &&
              participants.map((participant) => (
                <li
                  key={participant._id}
                  className="text-left"
                  style={{ fontSize: "1.1em" }}
                >
                  {participant.username}
                </li>
              ))}
          </ul>

          {isAuthenticated ? (
            <div>
              <TournamentSignUp
                participants={participants}
                userId={user._id}
                onClick={() => this.onSignUp(_id, user)}
              />
            </div>
          ) : (
            <Button block disabled>
              Log in to sign up for this tournament
            </Button>
          )}
          {isAuthenticated && user.username === hostedBy ? (
            <div>
              <StartTournament
                participants={participants}
                onClick={() => this.onStartTournament(_id, participants)}
              />
            </div>
          ) : null}
        </div>
      ) : (
        <TournamentStartPage /> // REMOVED THIS
      )
    }
    <br />
    <Link to="/">Back to Tournaments main page</Link>
  </div>
);

The idea was for what is shown to change once the Status is changed.

But when you click the link to get to this component, the UI flickers showing the "Closed" version first, and that's ugly. So I split em, the other component is now just in it's own file and this one is only going to render itself.

.. So I just removed that status==Open conditional.

So the same component from above now looks like

return (
  <div style={{ color: "lightgrey" }}>
    <h1 className="text-center">
      {title} <span style={{ fontSize: "0.5em" }}>by {hostedBy}</span>
    </h1>
    <h3>
      {" "}
      <TournamentDescription key={_id} title={title} />{" "}
    </h3>
    <br />
    <p className="text-center" style={{ color: "#56A8CBFF", fontSize: "2em" }}>
      ~ {status} for registration ~
    </p>

    <h4 className="text-left mt-5">
      {
        participants.length === 1 // THIS BREAKS
          ? `${participants.length} Registered Fighter` // THIS BREAKS
          : `${participants.length} Registered Fighters` // THIS BREAKS
      }
    </h4>

    <ul>
      {participants &&
        participants.map((participant) => (
          <li
            key={participant._id}
            className="text-left"
            style={{ fontSize: "1.1em" }}
          >
            {" "}
            {participant.username}
          </li>
        ))}
    </ul>

    {isAuthenticated ? (
      <div>
        <TournamentSignUp
          participants={participants}
          userId={user._id}
          onClick={() => this.onSignUp(_id, user)}
        />
      </div>
    ) : (
      <Button block disabled>
        Log in to sign up for this tournament
      </Button>
    )}
    {isAuthenticated && user.username === hostedBy ? (
      <div>
        <StartTournament
          participants={participants}
          onClick={() => this.onStartTournament(_id, participants)}
        />
      </div>
    ) : null}
    <br />
    <Link to="/">Back to Tournaments main page</Link>
  </div>
);

That breaks even though participants && participants.map() still works fine. Makes no sense to me.

The error I'm getting is Cannot read propery 'length' of undefined

To test it, I ran a console.log on participants and it shows two things in the console:

undefined
participants[]

That undefined thing is causing my component to break, but that apparently didn't exist before.
I cleared my data thinking it was something in there, but it's still happening (participants is an empty array right now, so it should be 0)

I don't see anything weird in what you're getting, perhaps status === "Open" was a guard clause to avoid undefined getting into that code, just add another guard clause where the error points at participants && participants.length === 1

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