this.props.location.state 在 React Link 路由器中未定义

this.props.location.state is undefined in React Link Router

我在 Stack Overflow 上看到了其中的几个问题,但 none 的修复似乎有效。 this.props.location.state 总是 returns 未定义。这是我的 AppContainerExamplePageParentExamplePage

import {Router, Route, Switch} from "react-router-dom";

class AppContainer extends Component {
  render() {
    return (
      <Router>
        <Switch>   
          <Route exact path="/page" component={Page}
          <Route exact path="/examplePage" component={ExamplePage}/>
        </Switch>
      </Router>
    )
  }
}
//has mapStateToProps and mapDispatch to Props here

export default connect(mapStateToProps, mapDispatchToProps)(AppContainer);

--

class Page extends Component {

  render() {
   return(
     <AnotherPage key=this.props.id>
   );
  }
    }

// has mapStateToProps here (this.props.id comes from here)

export default connect(mapStateToProps, mapDispatchToProps)(Page);

--

class AnotherPage extends Component {

  render() {
   return(
     <ExamplePageParent key=this.props.id>
   );
  }
    }

// has mapStateToProps here (this.props.id comes from here)

export default connect(mapStateToProps, null)(AnotherPage);

--

class ExamplePageParent extends Component {

  //pathName and dataPassed content filled, not relevant to question

  render() {
   return(
     <Link
       class={'link-styling'}
       target="_blank"
       rel="noreferrer"
       to={{pathname: this.state.pathName, state: {dataPassed: true} }}
     >
       Click Me
     </Link>
   );
  }
    }

//has mapStateToProps here

export default connect(mapStateToProps, null)(ExamplePageParent);

--

import {withRouter} from "react-router";

class ExamplePage extends Component {

  constructor(props) {
    super(props);

    //this has content:
    console.log(this.props.location);

    //undefined:
    console.log(this.props.location.state);
  }

  render() {
   return(
     // do stuff
   );
  }
}
export default withRouter(ExamplePage);

问题

  • 您正在使用 low-level Router,它需要一个 history 对象来定义一个 location 对象。
  • 代码正在链接到一个新的 window,因此该应用程序是 loaded/mounted 从头开始​​的,并且传递的路由状态不会被转移。

要解决未定义的问题 location,您有两种选择:

  1. history 包中导入自定义历史创建器:

    import { createBrowserHistory } from 'history';
    
    const history = createBrowserHistory();
    
    ...
    
    <Router history={history}>
      ...
    </Router>
    
  2. 使用 higer-level 路由器之一,即 BrowserRouterHashRouterMemoryRouter 等...:

    import { BrowserRouter as Router } from 'react-router-dom';
    
    ...
    
    <Router>
      ...
    </Router>
    

要解决在接收组件中访问“状态”的问题,您需要添加一些逻辑。当应用程序在新 window/tab 中启动时,状态不会传输,因此为了解决这个问题,您可以发送序列化为 queryString 搜索参数的路由状态。

<Link
  className={"link-styling"}
  target="_blank"
  rel="noreferrer"
  to={{
    pathname: this.state.pathName,
    search:
      "stuff=content&moreStuff=moreContent" + // existing search params
      "&dataPassed=This is the passed data.", // additional for state
    state: { dataPassed: "This is the passed data." }
  }}
>
  Click Me
</Link>

然后在 ExamplePage 中处理查询字符串以提取和删除添加的 "dataPassed" 查询参数,并使用填充的路由状态重定向先前存在的查询字符串。

class ExamplePage extends Component {
  componentDidMount() {
    const { history, location } = this.props;
    const { pathname, state, search } = location;

    console.log({ location });

    const searchParams = new URLSearchParams(search);
    let dataPassed;

    if (searchParams.has("dataPassed")) {
      dataPassed = searchParams.get("dataPassed");
      searchParams.delete("dataPassed");
    }
    history.replace({
      pathname,
      search: searchParams.toString(),
      state: { dataPassed }
    });
  }

  render() {
    return (
      ...
    );
  }
}