我试图在两个页面之间切换,但在学习时遇到了很多问题 react router
在 my 中App.js
,有一个底部,Cart
单击时将导航到我。
render() {
return (
<div>
<button type="button" className="btn btn-primary Bottom-right " onClick={(e) => this.handleSubmit(e)}>
Confirmed Order
</button>
<button type="button" className="btn btn-Primary">
<Link to="/displayCart" >Show Car</Link>
</button>
</div>
);
}
}
export default App;
在我的购物车组件中,也有类似的按钮可以将我导航回App
组件。
class Cart extends React.Component {
constructor(props){
super(props)
this.state={
cartData:null
}
}
componentDidMount() {
this.callApi()
.then(res => this.setState({ cartData: res.express}))
.catch(err => console.log(err));
}
callApi = async () => {
const response = await fetch('/myCart');
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
return body;
};
render(){
return(
<div className="col">
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to Shopping Center</h1>
</header>
</div>
<div>{ReactHtmlParser(this.state.cartData)}</div>
<button type="button Bottom-right" className="btn btn-Primary">
<Link to="/" >Keep Shopping</Link>
</button>
</div>
)
}
}
我的 index.js 包含两个组件,app JS 是默认组件。
ReactDOM.render(
<BrowserRouter>
<switch>
<div>
<Route exact path="/displayCart" component={Cart}/>
<Route component={App} />
</div>
</switch>
</BrowserRouter>,
document.getElementById('root')
);
现在它们在很多层面上都存在缺陷:
1:当我点击显示购物车时,而不是渲染新视图。购物车组件呈现在视图顶部,而 App 仍然呈现。
2:单击 Show Cart 后,我单击 Show App 返回到我的 App 组件,但是控制台打印:
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in Cart (created by Route)
3:如果我从 CartApp
返回组件时更改了组件中的状态,则状态不会刷新。例如(例如,items 中的布尔值“purchase”。)当我从 Cart 中的 App 组件返回时,状态保持为真,相反,我希望它返回到初始状态。App
component
我跟着教程,但它只是坏了。我做错了什么
所以警告是因为即使在您返回应用程序后setState
也会被调用,<Cart />
这意味着到那时购物车组件已卸载。
您应该跟踪何时Cart
被卸载。
您可以通过在Cart
组件中创建一个变量来实现这一点,例如_isMounted
,然后使用生命周期事件componentWillUnmount
进行跟踪。
componentWillUnmount(){
_isMounted =false
}
然后就在使用 setState 之前,快速检查以确保_isMounted
为真。
this.callApi()
.then(res => if(isMounted){
this.setState({ cartData: res.express}))
}
.catch(err => console.log(err));
显然,您还需要更改_isMounted
为 true 使用ComponentDidMount
关于应用程序的状态不是“刷新”...这是因为当您从应用程序 > 购物车 > 应用程序转到时,应用程序组件永远不会卸载和再次安装。
要解决此问题,请告诉switch
仅<App />
在 url 与主页完全匹配时使用exact path="/"
<switch>
<div>
<Route exact path="/displayCart" component={Cart}/>
<Route exact path="/" component={App} />
</div>
</switch>
现在,如果您想跟踪状态更改,即使在 API 调用完成之前关闭(卸载),那么您应该在其中创建一个函数<App/>
,setState
为您执行此操作并将其作为道具传递给<Cart />
内部,然后从内部传递您可以调用这个 prop 函数。
这只会在你把你的 React Router 的东西放在里面时才有效
我这样做的方式是这样的: - index.js 总是加载 - 在我内部然后重定向到显示正确的组件
这意味着始终安装。但是它让我使用 App 的状态作为默认的“主”状态,因为我从不卸载它,所以它始终存在。所以如果我有一个像...这样的子组件,我可以给 Cart 一个函数。无论是否仍然安装/显示,此功能都会改变其状态。
如果您像这样重组您的应用程序,那么您可以执行以下操作:
App.js添加一个函数来改变它的状态。
changeState(key, value){
this.setState({
key : value
}
}
现在将此函数作为道具传递
<BrowserRouter>
<switch>
<div>
<Route exact
path="/displayCart"
render={
(props) => <Cart {...props}
changeStateinApp={this.changeState} />
}
/>
<Route component={App} />
</div>
</switch>
</BrowserRouter>,
Cart.js现在调用这个函数
this.callApi()
.then(res =>
this.props.changeStateinApp(cartData, res.express)
.catch(err => console.log(err));
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句