我正在和Reaction一起做一个项目,我正在做一个简单的history.push(),只是为了导航到另一个组件.除了导航到另一个组件之外,我还希望使用history.push({state: []})来获取一些数据.

要访问另一个组件的数据,我使用useLocation()并使用Location.State访问它. 我在应用程序上切换了语言(语言逻辑设置为setLocalStorage()),突然location.state得到了undefined. 我在一些文章中读到location.state在重新渲染时得不到定义.我没有找到明确规定这一点的东西,甚至在react-router-dom文档中也没有.同样,当我重新加载页面时,location.state不会变成undefined.

我的问题是,为什么在重新呈现页面时会发生这种情况. 这样传递数据是不是最好的做法?如果不是,将其传递给另一个组件以避免这些错误的最佳实践是什么?

下载中心

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { Dropdown } from 'react-bootstrap';
import classNames from 'classnames';

import enFlag from './flags/uk.jpg';
import italyFlag from './flags/italy.jpg';
import { useTranslation } from 'react-i18next';

// get the languages
const Languages = [
  {
    name: 'English',
    flag: enFlag,
    short_name: 'en'
  },
  {
    name: 'Italian',
    flag: italyFlag,
    short_name: 'it'
  }
];

const 下载中心 = () => {
  const [dropdownOpen, setDropdownOpen] = useState<boolean>(false);
  const [selectedLanguage, setSelectedLanguage] = useState(
    localStorage.getItem('defaultLang') !== null
      ? Languages.find(function (item: { name: string; flag: string; short_name: string }) {
          return item.short_name == localStorage.getItem('defaultLang');
        })
      : Languages[0]
  );

  const [t, i18n] = useTranslation('common');
  /*
   * toggle language-dropdown
   */
  const toggleDropdown = () => {
    setDropdownOpen(!dropdownOpen);
  };

  const changeLanguage = async (lang: any) => {
    i18n.changeLanguage(lang.short_name);
    setSelectedLanguage(lang);
    localStorage.setItem('defaultLang', lang.short_name);
  };

  return (
    <Dropdown show={dropdownOpen} onToggle={toggleDropdown}>
      <Dropdown.Toggle
        id='dropdown-languages'
        as='a'
        onClick={toggleDropdown}
        className={classNames('nav-link waves-effect waves-light', {
          show: dropdownOpen
        })}>
         <img src={selectedLanguage.flag} alt={selectedLanguage.name} height='16' />
      </Dropdown.Toggle>
      <Dropdown.Menu className='dropdown-menu dropdown-menu-end'>
        <div onClick={toggleDropdown}>
          {(Languages || []).map((lang, i) => {
            return (
              <Link
                to='#'
                onClick={() => changeLanguage(lang)}
                className='dropdown-item notify-item'
                key={i + '-lang'}>
                <img src={lang.flag} alt={lang.name} className='me-1' height='12' />
                <span className='align-middle'>{lang.name}</span>
              </Link>
            );
          })}
        </div>
      </Dropdown.Menu>
    </Dropdown>
  );
};

export default 下载中心;

推荐答案

Issue

问题似乎出在语言 Select 下拉菜单中使用的链接目标上.他们向"/#"个任何现有的州发布导航操作.这是正在被清除的路由状态.

Solution

您可以直接导航到当前位置,而不是导航到"/#"

const LanguageDropdown = () => {
  const location = useLocation(); // <-- current location, including any state

  ...

  return (
    <Dropdown show={dropdownOpen} onToggle={toggleDropdown}>
      ...
      <Dropdown.Menu className='dropdown-menu dropdown-menu-end'>
        <div onClick={toggleDropdown}>
          {(Languages || []).map((lang, i) => {
            return (
              <Link
                to={location} // <-- current location, including any state
                onClick={() => changeLanguage(lang)}
                className='dropdown-item notify-item'
                key={i + '-lang'}
              >
                ...
              </Link>
            );
          })}
        </div>
      </Dropdown.Menu>
    </Dropdown>
  );
};

export default LanguageDropdown;

如果你有效地停留在当前页面,你也可以省略toprops ,取消导航操作.

const LanguageDropdown = () => {
  ...

  return (
    <Dropdown show={dropdownOpen} onToggle={toggleDropdown}>
      ...
      <Dropdown.Menu className='dropdown-menu dropdown-menu-end'>
        <div onClick={toggleDropdown}>
          {(Languages || []).map((lang, i) => {
            return (
              <Link
                onClick={(e) => {
                  e.preventDefault(); // <-- prevent navigation action
                  changeLanguage(lang);
                }}
                className='dropdown-item notify-item'
                key={i + '-lang'}
              >
                ...
              </Link>
            );
          })}
        </div>
      </Dropdown.Menu>
    </Dropdown>
  );
};

export default LanguageDropdown;

演示

Edit why-location-state-gets-undefined-when-the-page-reloads

Reactjs相关问答推荐

无法在列表中看到文本

有没有方法覆盖NextJS 14中的布局?

REACT路由DOM根据参数呈现不同的路由

Next.js:提交表单时状态尚未就绪

如何访问子集合中的文档?

Reaction上下文值无法传递给其他组件

根据用户 Select 的注册类型更改表单字段

useRef()的钩子调用无效

如何使用 React 获取表单中的所有值?

Material-UI 和 React Hook 表单不记录值

React useContext 的未定义返回值

拖放 - 将排序保存到数组字段

React Context API 在 Next.js 中更改路由时获取默认数据

ReactJS 中的图像加载顺序

如何在不使用 Axios 的情况下将图像文件从 React.js 发送到 Spring Boot Rest API?

我可以更改 styled() 中的响应吗? (MUI v5)

导航到屏幕时,react 本机上下文状态变为未定义

用 scss 覆盖 MUI

React如何在用户登录后等待当前用户数据被获取

将 set statehook 函数传递给子路由组件.解构错误