Props.location не определен с компонентом маршрута

я пытаюсь запустить фрагмент кода, как показано ниже:

class App extends Component {
  render() {
    return (
      <Router>
        <div className = "App">
          <Navbar></Navbar>
          <Routes>
            <Route path = "/" element = {<Home></Home>} />
            <Route path = "/about" element = {<About></About>} />
            <Route path = "/contact" element = {<Contact></Contact>} />
            <Route path = "/challenges/*" element = {<Challenges></Challenges>} />
            <Route path = "*" element = {<NotFound />} />
          </Routes>
        </div>
      </Router>
    );
  }
}
let a = 0;

const Challenges = (props) => {
  console.info(++a);
  console.info(window.location.pathname);
  const path = props.location.pathname;
  const slug = path.split("/").slice(path.split("/").length - 1)[0];
  const challenge = challenges.find((challenge) => challenge.slug === slug);
  return (
    <div>
      <h1>30 Days Of React Challenge</h1>
      <ul>
        {challenges.map(({ name, slug }) => (
          <li key = {name}>
            <NavLink to = {`/challenges/${slug}`}>{name}</NavLink>
          </li>
        ))}
      </ul>
      <Routes>
        <Route
          exact
          path = "/challenges"
          element = {<h1>Choose any of the challenges</h1>}
        />

        <Route path = {path} element = {<Challenge challenge = {challenge} />} />
      </Routes>
    </div>
  );
};

я хочу получить путь в компоненте маршрута Challenges, но он выдает ошибку: Не удается прочитать свойства неопределенного (чтение «имя пути») я пытаюсь зарегистрировать переменную «a» и «window.location» для проверки, и она регистрируется два раза следующим образом:

1
/challenges
2
/challenges

Мой вопрос в том, почему я не могу принять значение props.location.pathname и почему он запускается два раза, а во второй раз выдает ошибку, почему не в первый раз. Спасибо за помощь! Надеюсь, у тебя хороший день.

Компоненты перерисовываются по разным причинам: их свойства, контекст или состояние изменились, или их родитель(и) перерендерились. Если вы оберните свой компонент Challenges с помощью React.memo, вы можете предотвратить его повторный рендеринг, если его свойства или состояние не изменятся, но вам часто не нужно беспокоиться об этом. Я также ожидал бы, что challenges.find потерпит неудачу, поскольку вы нигде не определили challenges (по крайней мере, в показанном коде)

Matthew Herbst 06.04.2022 20:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
22
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблемы)

  1. Компоненты react-router-dom v6 Route, отображаемые с помощью element prop, не получают реквизит маршрута.
  2. Дочерние компоненты маршрута должен используют реагирующие хуки для доступа к контексту маршрута, т. е. useParams, useLocation, useNavigate и т. д., и поэтому должны быть функциональными компонентами.
  3. Вызовы console.info находятся в теле функции, так что это непреднамеренные побочные эффекты. Вероятно, поэтому они вызываются дважды, предполагая, что приложение визуализируется в компонент React.StrictMode.

Решение

Challenges следует использовать хук uselocation для доступа к имени пути. Переместите журналы консоли в хук useEffect, чтобы они вызывались один раз за рендеринг в ДОМ.

const Challenges = (props) => {
  const { pathname } = useLocation();

  useEffect(() => {
    console.info(++a);
    console.info(pathname);
  });

  const path = pathname;
  const slug = path.split("/").slice(path.split("/").length - 1)[0];
  const challenge = challenges.find((challenge) => challenge.slug === slug);

  return (
    <div>
      <h1>30 Days Of React Challenge</h1>
      <ul>
        {challenges.map(({ name, slug }) => (
          <li key = {name}>
            <NavLink to = {`/challenges/${slug}`}>{name}</NavLink>
          </li>
        ))}
      </ul>
      <Routes>
        <Route
          path = "/challenges"
          element = {<h1>Choose any of the challenges</h1>}
        />

        <Route path = {path} element = {<Challenge challenge = {challenge} />} />
      </Routes>
    </div>
  );
};

v6 API-ссылка

Другие вопросы по теме