React路由器使用当前路由传递回调给子组件

时间:2018-05-19 11:25:17

标签: javascript reactjs callback react-router

我正在使用反应路由器做出反应。我的一些组件定义了子路由,因此我想向它们传递一个回调函数,该回调函数可以返回到特定的路由/组件。我想避免将字符串传递给特定路由(因为在代码中发生路由更改时的依赖性)。所以我更喜欢传递一个回调并用match.url的值填充它。

但这不起作用:match.url不是传递值,而是始终引用当前路径。

父组件(简化):

export class ParentComponent extends React.Component {
  render() {
    const { history, match, contentId } = this.props;

    return (
      <div>
        <div>
          <div>Block 1</div>
          <div>Block 2</div>
          <div>Block 3</div>
        </div>
        {contentId && <MyChildComponent content={contentId} goBack={() => history.push(match.url)} />}
      </div>
    );
  }
}

我的孩子组件(简化):

export class MyChildComponent extends React.PureComponent {
  render() {
    return (
      (
        <React.Fragment>
          <div role="dialog" onClick={this.props.goBack} />
        </React.Fragment>),
    );
  }
}

我的路由器:

const Routes = () => (
  <Router history={createBrowserHistory()}>
    <div>
      <Route path="/result/:contentId?" component={ParentComponent} />
    </div>
  </Router>
);

所以,当我去/结果时,我看到 - 正如预期的那样 - 除了子组件之外的所有组件。当导航到/ result / someId时,我看到子组件,但goBack只引用当前页面而不是前一页面。

3 个答案:

答案 0 :(得分:1)

constructor(props){
   super(props);
   this.goBack = this.goBack.bind(this);
}

goBack(){
    this.props.history.goBack(); // You're not calling it from history
}

.....

<button onClick={this.goBack}>Go Back</button>

答案 1 :(得分:0)

我认为您正在使用push导航到另一条路线。因此,当您执行history.push('/result/someId')时,您将向历史堆栈添加另一个条目,因此goBack将导航到堆栈中的前一个条目/result。它就好像你是一个普通的网站并点击一个链接 - 即使改变的是一些动态参数,你仍然可以回去。

如果您不想添加历史记录堆栈,请使用history.replace('/result/someId')

请参阅navigating with history

答案 2 :(得分:0)

我发现我的核心问题是我需要在父组件中至少有一部分子路由。这导致在子路径发生变化时也在父组件中更改路径道具。

我的解决方案:将当前位置存储在父组件的构造函数中,并将其作为prop传递给子组件以进行引用。它有效,但缺点是无法直接访问子组件路由,因为它们不会引用回正确的父路径。对于我的用例,这很好但欢迎改进。

父组件

export class ParentComponent extends React.Component {
    constructor(props) {
        super(props);
        this.location = this.props.location.pathname;
    }

    render() {
      return (
          {contentId && <MyChildComponent content={contentId} goBack={() => 
          history.push(this.location)} />}
      )
    }