折腾:
【已解决】ReactJS导航栏显示返回按钮和标题以及右边图标
期间,需要实现:
对于不同的路由进来后,除了更新顶部Header中的图标,包括左边的返回按钮,同时要给返回按钮添加点击事件,或者是Link,以便于实现返回上一页
react router back link
preact router back link
javascript – react-router go back a page how do you configure history? – Stack Overflow
reactjs – Programmatically navigate using react router – Stack Overflow
preact-router back
用:
|   goBackPage(){     console.log(`this.context.router=${this.context.router}`);     this.context.router.goBack();   }           <a onClick={this.goBackPage}>             <span/>           </a> | 
结果出错:
| index.js?5c2a:415 Uncaught TypeError: Cannot read property ‘router’ of undefined     at Object.goBackPage [as click] (eval at 349 (0.bd5b650….hot-update.js:7), <anonymous>:453:54)     at HTMLAnchorElement.eventProxy (eval at <anonymous> (bundle.js:771), <anonymous>:96:32) | 
preact-router browserhistory back
[PReact] Handle Simple Routing with preact-router-IT大道
|   goBackPage(){     // console.log(`this.context=${this.context}`);     console.log(`browserHistory=${browserHistory}`);     console.log(`router=${router}`);     console.log(`route=${route}`);     console.log(`hashHistory=${hashHistory}`);     console.log(`hashHistory._preactRouter=${hashHistory._preactRouter}`);     console.log(`this._preactRouter=${this._preactRouter}`);     // this.context.router.goBack();     // browserHistory.goBack();     // route(-1);     hashHistory.goBack();   } | 
都不行。
react router current route
preact router current route
暂时放一放,因为目前github无法打开,很多帖子和preact-router源码没法看。
等github能访问了,再弄。
然后目前用代码:
app.js
| @connect(reducer, bindActions(actions)) export default class App extends Component {   state = {     curUrl : "/",     prevUrl : "/"   };   constructor(props) {     super(props);     autoBind(this);   }   handleRoute = e => {     console.log(e);     // console.log(e.router.activeClassName);     console.log(e.router);     // console.log(e.router.title);     const currentUrl = e.url;     // const currentUrl = "/uapp" + e.url;     // console.log(this.currentUrl);     console.log(currentUrl);     const previousUrl = e.previous;     console.log(previousUrl);     this.setState({       curUrl : currentUrl,       prevUrl : previousUrl     });     console.log(this.state.curUrl);     window.scrollTo(0, 0);   };   render() {     const prop = this.props;     return (       <div id="app">         <Loading show={prop.globalLoadingShown}/>         {/*<Header title={this.state.currentTitle}/>*/}         <Header curUrl={this.state.curUrl} prevUrl={this.state.prevUrl}/> | 
header/index.js
| export default class Header extends Component {   state = {     curUrl : "",     prevUrl : "1"   }   constructor(props) {     super(props);     // this.state.curUrl = this.props.curUrl;     // this.state.prevUrl = this.props.prevUrl;     console.log(`Header constructor: this.state.curUrl=${this.state.curUrl}, this.state.prevUrl=${this.state.prevUrl}, this.props.curUrl=${this.props.curUrl}, this.props.prevUrl=${this.props.prevUrl}`);   }   componentWillReceiveProps(nextProps) {     this.setState({       curUrl: nextProps.curUrl,       prevUrl: nextProps.prevUrl     });     // this.forceUpdate();   }   render() {     const pageType = this.parsePageType(this.state.curUrl);     console.log(`Header render: this.state.curUrl=${this.state.curUrl}, this.state.prevUrl=${this.state.prevUrl}, this.props.curUrl=${this.props.curUrl}, this.props.prevUrl=${this.props.prevUrl}`);     return (       <header class={style.header_div}>         <div class={style.header_con}>           { this.showLeftIcon(pageType, this.state.prevUrl) }           <div class={style.top_tit}>{pageType.title}</div>           { this.showRightIcon(pageType) }         </div>       </header>     );   }   showLeftIcon(curPageType, prevUrl){     console.log(`showLeftIcon: prevUrl=${prevUrl}`);     if (curPageType.left.icon === HEADER_ICON.NONE) {       return null;     } else if (curPageType.left.icon === HEADER_ICON.BACK) {       return (           <Link href={prevUrl}>             <span/>           </Link>       );     } else if (curPageType.left.icon === HEADER_ICON.SWITCH_COW_FARM) {       return (           <Link href={curPageType.left.link} class={style.home_qc} >             切换牛场           </Link>       );     }     return null;   } | 
虽然实现了基本的,通过prevUrl,实现返回上一页,但是会出现嵌套死循环:

点击子页面,比如 处理 或者右上角的加号,进入子页面的子页面

但是此时点击返回,可以返回上一页:

但是再点击 返回,还是回到之前的子页面了(而非期望的主页面)

所以,还是没有真正解决问题。
-》
如果给每个页面,都强制指定一个前一页,则显得很麻烦。
-》希望还是可以通过history back类似的逻辑,即页面调用stack栈,智能的实现页面跳转。
所以还是:
等github可以访问后,再去研究
preact-router是否有history back之类的功能
preact-router history back
Full hash-routing using preact-router · Issue #153 · developit/preact-router
Route Transitions · Issue #29 · developit/preact-router
preact-router history
javascript – How to use React Router with Preact – Stack Overflow
preact-router go back
reactjs – Using goBack function from react-router-redux – Stack Overflow
然后用了back的代码,结果点击返回按钮时出错:
【间接解决】Preact-Router调用传递过去的history的back时出错:Uncaught TypeError Illegal invocation
【总结】
Preact-router是支持history.back()去返回上一页的,但是只能在父页面中使用,即只能在Router所在的页面使用。
此处不能直接把history作为参数(比如叫routerHistory)传递给子页面,否则子页面中直接调用routerHistory.back是行不通的,会出错:Uncaught TypeError: Illegal invocation
解决办法是:
利用子页面调用父页面的函数,即可间接实现此效果:
把父页面的history.back()单独弄成函数,传递给子页面,然后子页面即可随时调用此函数,实现返回前一页了。
具体代码是:
父页面app.js
| import { Router } from ‘preact-router’; import { browserHistory } from ‘preact-router’; import Header from ‘../components/header’; @connect(reducer, bindActions(actions)) export default class App extends Component {   state = {     curUrl : "/",     prevUrl : "/",     routerHistory : null   };   constructor(props) {     super(props);     autoBind(this);   }   handleRoute = e => {     console.log("handleRoute:");     console.log(e);     // console.log(e.router.activeClassName);     console.log(e.router);     // console.log(e.router.title);     const currentUrl = e.url;     // const currentUrl = "/uapp" + e.url;     // console.log(this.currentUrl);     console.log(currentUrl);     // console.log(browserHistory);     console.log(`history.location=${history.location}`);     console.log("now do history.back()");     // history.back();     // console.log(`this.props.history=${this.props.history}`);     // console.log(`this.state.history=${this.state.history}`);     const previousUrl = e.previous;     console.log(previousUrl);     this.setState({       curUrl : currentUrl,       prevUrl : previousUrl,       routerHistory : history     });     console.log(this.state.curUrl);     window.scrollTo(0, 0);   };   goBackFunc(){     console.log(`goBackFunc: history=${history}`);     console.log(history);     console.log(history.back);     console.log("+++++ now do history.back()");     history.back();   }   render() {     const prop = this.props;     return (       …        <Header curUrl={this.state.curUrl} prevUrl={this.state.prevUrl} routerHistory={this.state.routerHistory} goBackFunc={this.goBackFunc}/>         <div class="container">           <Router onChange={this.handleRoute} history={browserHistory}>           {/*<Router onChange={this.handleRoute}>*/}             <Main path="/" />             <Profile path="/profile" /> | 
子页面Header/index.js
| export default class Header extends Component {   state = {     curUrl : "",     prevUrl : "1",     routerHistory : null   }   constructor(props) {     super(props);     // this.state.curUrl = this.props.curUrl;     // this.state.prevUrl = this.props.prevUrl;     console.log(`Header constructor: this.state.curUrl=${this.state.curUrl}, this.state.prevUrl=${this.state.prevUrl}, this.props.curUrl=${this.props.curUrl}, this.props.prevUrl=${this.props.prevUrl}`);   }   componentWillReceiveProps(nextProps) {     this.setState({       curUrl: nextProps.curUrl,       prevUrl: nextProps.prevUrl,       routerHistory : nextProps.routerHistory     });     // this.forceUpdate();     // console.log(`Header componentWillReceiveProps: this.state.routerHistory=${this.state.routerHistory}, history=${history}, route=${route}, getCurrentUrl=${getCurrentUrl}`);     console.log(`Header componentWillReceiveProps: this.state.routerHistory=${this.state.routerHistory}`);   }   render() {     const pageType = this.parsePageType(this.state.curUrl);     console.log(`Header render: this.state.curUrl=${this.state.curUrl}, this.state.prevUrl=${this.state.prevUrl}, this.props.curUrl=${this.props.curUrl}, this.props.prevUrl=${this.props.prevUrl}`);     return (       <header class={style.header_div}>         <div class={style.header_con}>           { this.showLeftIcon(pageType, this.props.goBackFunc) }           {/*<a onClick={this.state.routerHistory.back}>*/}           {/*<a onClick={this.state.routerHistory !== null ? this.state.routerHistory.back : ()=>{}}>*/}           {/*<a onClick={this.props.goBackFunc}>             <span/>           </a>*/}           <div class={style.top_tit}>{pageType.title}</div>           { this.showRightIcon(pageType) }         </div>       </header>     );   }           // <a onClick={this.goBackPage}>           // <a onClick={route(prevUrl)}>           //   <span/>           // </a>           // <Link href={prevUrl}>           //   <span/>           // </Link>   // showLeftIcon(curPageType, prevUrl){   //   console.log(`showLeftIcon: prevUrl=${prevUrl}`);   // showLeftIcon(curPageType, curState){   showLeftIcon(curPageType, goBackFunc){     console.log(`showLeftIcon: goBackFunc=${goBackFunc}`);     // console.log(`showLeftIcon: curState=${curState}`);     // console.log(`showLeftIcon: curState.routerHistory=${curState.routerHistory}`);     // console.log(curState.routerHistory);     // if (curState.routerHistory !== null) {     //   console.log(curState.routerHistory.back);     //   const backFunction = curState.routerHistory.back;     //   console.log(backFunction);     // }     if (curPageType.left.icon === HEADER_ICON.NONE) {       return null;     } else if (curPageType.left.icon === HEADER_ICON.BACK) {       return (           // <a onClick={backFunction}>           // <a onClick={curState.routerHistory.back}>           <a onClick={goBackFunc}>             <span/>           </a>       );     } else if (curPageType.left.icon === HEADER_ICON.SWITCH_COW_FARM) {       return (           <Link href={curPageType.left.link} class={style.home_qc} >             切换牛场           </Link>       );     }     return null;   } | 
效果是:
(1)比如最开始在首页

(2)点击了进入配种子页面

(3)点击处理

(4)点击返回之前页面

(5)点击加号去新增

(6)再点击返回

(7)此时,重点来了:点击返回就不会出现页面在之前的 处理和新增页面死循环的情况了,就可以正常返回首页了:

转载请注明:在路上 » 【已解决】Preact-Router中如何通过路由实现返回上一页