0

我有一个带有按钮、通用背景和通用标题以及更改嵌套组件的屏幕。在此屏幕内,我想通过单击按钮来更改嵌套组件。嵌套的组件必须通过左右按钮在一个圆圈内相互更改。到目前为止,我做了很多尝试来实现这一点(我尝试使用 withRouter 来实现),我只给你我尝试的代码之一,但所有这些都不起作用。我没有收到任何错误,我看到浏览器中的路线正在改变,但屏幕没有,我只看到第一个嵌套组件。SOF 上有关于此的问题,但它们与旧版本的 react-router 有关。这是我的代码,如果您需要更多信息,请随时在评论中提问。

import React, { Component } from 'react';

import { Link, 
         BrowserRouter as Router,
         Route,
         Switch,
         withRouter } from 'react-router-dom';

import Info1 from './info/info1';
import Info2 from './info/info2';
import Info3 from './info/info3';
import Info4 from './info/info4';


class Info extends Component {

   constructor(props) {
    super(props);

    this.currentIndex = 1;

  }




  componentDidMount() {


  }

  leftHandler() {
    console.log("left click");
    var temp = this.currentIndex;
    this.changeScreen(--temp);
  }

  rightHandler() {
    console.log("right click");
    var temp = this.currentIndex;
    this.changeScreen(++temp);
  }

  changeScreen(index) {

    const numberOfScreens = 4;

    if(index < 1)
        this.currentIndex = numberOfScreens;
    else if(index > numberOfScreens)
        this.currentIndex = 1;
    else
        this.currentIndex = index;
    this.props.history.push("/info/" + this.currentIndex);
  }






  render() {


    return (
      <Router>
       <div className="info-common">
           <img className="game-title info-game"/>
           <Switch>
                 <Route path="/info/1" component={ Info1 }/>
                <Route path="/info/2" component={ Info2 }/>
                <Route path="/info/3" component={ Info3 }/>
                <Route path="/info/4" component={ Info4 }/>
            </Switch>
            <Link to="/rings"><button className="back-info-btn">назад</button></Link>
            <button onClick={ this.leftHandler.bind(this) } className="left-info-btn"></button>
            <button onClick={ this.rightHandler.bind(this)} className="right-info-btn"></button>
       </div>
      </Router>
    );
  }

}


Info.propTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired,
    }).isRequired,
  location: React.PropTypes.isRequired,
};

export default withRouter(Info);

编辑:虽然我接受了给定的答案,但我没有测试它,在我的项目中我使用了这个解决方案:

app.js 

import {
  BrowserRouter as Router,
  Route,
  Link
} from 'react-router-dom';

...


render() {

    return (
      <div id='game-container' width="1236" height="634">
        <Router>
        <div>
          <Route path="/info" component={ Info }/>
        </div>
        </Router>
      </div>
    );
  }

然后在信息本身:

Info.js

class Info extends Component {

   constructor(props) {
   super(props);

   this.currentIndex = 1;

  }





  leftHandler() {
    console.log("left click");
    var temp = this.currentIndex;
    this.changeScreen(--temp);
  }

  rightHandler() {
    console.log("right click");
    var temp = this.currentIndex;
    this.changeScreen(++temp);
  }

  changeScreen(index) {

    const numberOfScreens = 4;

    if(index < 1)
        this.currentIndex = numberOfScreens;
    else if(index > numberOfScreens)
        this.currentIndex = 1;
    else
        this.currentIndex = index;
    this.props.history.push("/info/" + this.currentIndex);
  }


  render() {


    return (
       <div className="info-common">
           <img className="game-title info-game" src={ this.drawGame() }/>
            <Switch>
                <Route path={`${this.props.match.path}/1`} component={ Info1 }/>
                <Route path={`${this.props.match.path}/2`} component={ Info2 }/>
                <Route path={`${this.props.match.path}/3`} component={ Info3 }/>
                <Route path={`${this.props.match.path}/4`} component={ Info4 }/>
            </Switch>
            <Link to="/rings"><button className="back-info-btn">назад</button></Link>
            <button onClick={ this.leftHandler.bind(this) } className="left-info-btn"></button>
            <button onClick={ this.rightHandler.bind(this)} className="right-info-btn"></button>
       </div>
    );
  }

}

Info.propTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired,
    }).isRequired,
  location: React.PropTypes.object.isRequired,
};

export default withRouter(Info);
4

1 回答 1

1

如果将组件包装在 中withRouter,则只能在 a 中使用它<Router>,就像<Route>s 等一样。

要使您的示例正常工作,您需要创建<Info>的孩子<Router>,因为它使用withRouter. 首先,<Router>render方法中移除 ,并将 渲染<div>为顶级组件:

render() {
  return (
    <div className="info-common">
      <img className="game-title info-game"/>
      <Switch>
        <Route path="/info/1" component={ Info1 }/>
        <Route path="/info/2" component={ Info2 }/>
        <Route path="/info/3" component={ Info3 }/>
        <Route path="/info/4" component={ Info4 }/>
      </Switch>
      <Link to="/rings">
        <button className="back-info-btn">назад</button>
      </Link>
      <button onClick={ this.leftHandler.bind(this) } className="left-info-btn"></button>
      <button onClick={ this.rightHandler.bind(this)} className="right-info-btn"></button>
    </div>
  )
}

然后,无论您在哪里渲染<Info />,都<Router><Info /></Router>改为渲染。或者,添加一个呈现两者的额外组件,并使用该组件而不是<Info />.

// Option 1: render <Router> wherever you use <Info>
import Info from './info';
...
ReactDOM.render(<Router><Info /></Router>);

// Option 2: add another component that wraps <Info> in a Router,
// either as the new export of the module, or as a new module
const App = () => (
  <Router>
    <Info />
  </Router>
);
export default App;
于 2017-03-30T01:37:13.643 回答