РЕАГИРУЕТ на рендеринг массива из состояния redux в пользовательском интерфейсе

#javascript #reactjs #user-interface #components #mern

#javascript #reactjs #пользовательский интерфейс #Компоненты #мерн

Вопрос:

Вот головокружительный вопрос! У меня этот компонент моего приложения был завершен некоторое время. Я решил сделать небольшой, казалось бы, незначительный рефакторинг, который приводит к нарушению чего-то странного:

 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 amp;amp;
              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 amp;amp; 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>
);
  

Идея заключалась в том, чтобы то, что отображается, менялось при изменении статуса.

Но когда вы нажимаете на ссылку, чтобы перейти к этому компоненту, пользовательский интерфейс мигает, показывая сначала «Закрытую» версию, и это некрасиво. Итак, я разделил их, другой компонент теперь находится только в своем собственном файле, и этот будет отображать только себя.

.. Поэтому я просто удалил это условие status==Open.

Итак, тот же компонент сверху теперь выглядит так

 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 amp;amp;
        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 amp;amp; user.username === hostedBy ? (
      <div>
        <StartTournament
          participants={participants}
          onClick={() => this.onStartTournament(_id, participants)}
        />
      </div>
    ) : null}
    <br />
    <Link to="/">Back to Tournaments main page</Link>
  </div>
);
  

Это ломается, хотя participants amp;amp; participants.map() все еще работает нормально. Для меня это не имеет смысла.

Ошибка, которую я получаю, такова Cannot read propery 'length' of undefined

Чтобы протестировать это, я запустил консоль.войдите в participants систему, и в консоли отобразятся две вещи:

 undefined
participants[]
  

Эта undefined вещь приводит к поломке моего компонента, но, по-видимому, раньше этого не было.
Я очистил свои данные, думая, что там что-то есть, но это все еще происходит (участники — это пустой массив прямо сейчас, поэтому он должен быть 0)

Ответ №1:

Я не вижу ничего странного в том, что вы получаете, возможно status === "Open" , это было защитное предложение, чтобы избежать undefined попадания в этот код, просто добавьте другое защитное предложение, на которое указывает ошибка participants amp;amp; participants.length === 1

Комментарии:

1. Хорошо, я сохранил это условие и просто вставил null . Однако мне это не нравится, потому что при первом рендеринге компонент быстро мигает между null (или другим компонентом, который у меня был изначально), а ЗАТЕМ отображает правильный. Это выглядит некрасиво. Просто Отрисовывая компонент без условного обозначения, он отображается без мигания чего-либо еще. Но опять же.. эта проблема. Я буду продолжать пробовать. Хотя спасибо

2. @Cin88 когда данные загружаются из асинхронного источника, у вас всегда будет неопределенное состояние, если вы не используете SSR, я думаю, обычно вы ставите счетчик или индикатор загрузки во время загрузки данных, я не совсем понимаю вашу идею о том, чтобы избежать мерцания

3. Мерцание в основном.. когда я ставлю условие, оно гласит: «Если статус открыт, показывать ПЕРВЫМ, в противном случае показывать ВТОРЫМ», но то, что он всегда делает, даже если статус открыт, сначала он показывает ВТОРОЙ очень быстро, а затем показывает ПЕРВЫЙ. Я хотел, чтобы он просто показывал ЭТО без этого мерцания. Что касается размещения счетчика.. это отличная идея. Но я действительно.. Я понятия не имею, как это сделать. И что такое SSR?

4. @Cin88 вы пробовали мое предложение оставить его таким, каким он был у вас, и только добавлять participants amp;amp; раньше participants.length === 1 ? SSR означает рендеринг на стороне сервера

5. РЕДАКТИРОВАТЬ Это сработало. Мне пришлось поместить participants amp;amp; participants.length для всех трех разделов троичного