折腾:
【已解决】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中如何通过路由实现返回上一页