React 路由器:新组件仅在现有视图上呈现
React router: new component only render on existing view
我正在尝试在两个页面之间切换,但是 运行 在学习过程中遇到很多问题 react router
在我的 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 Component,但是控制台打印:
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:如果我在 App
组件中更改了状态,当我从购物车 component
返回到 App
组件时,状态没有得到刷新。例如(例如,项目中的布尔值 "purchase"。)当我从购物车的 App 组件返回时,状态保持为真,相反,我希望它回到初始状态。
我按照教程进行操作,但它只是坏了。我做错了什么
所以警告是因为 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));
显然您还需要使用 ComponentDidMount
将 _isMounted
更改为 true
关于应用程序的状态不是 'refreshing'...这是因为当您从应用程序 > 购物车 > 应用程序进入时,应用程序组件永远不会卸载和再次安装。
要解决此问题,请使用 exact path="/"
告诉 switch
仅在 url 与主页完全匹配时安装 <App />
组件
<switch>
<div>
<Route exact path="/displayCart" component={Cart}/>
<Route exact path="/" component={App} />
</div>
</switch>
现在,如果您想跟踪状态变化,即使在 API 调用完成之前已关闭(卸载),那么您应该在 <App/>
中创建一个函数来执行 setState
并将其作为道具传递给 <Cart />
然后从内部您可以调用此道具功能。
这只有在你将 React Router 的东西放在
中时才有效
我的做法是这样的:
- index.js 始终加载
- 然后在我内部重定向到显示正确的组件
这意味着始终挂载。但是,它让我可以使用 App 的状态作为默认 "main" 状态,该状态始终存在,因为我从未卸载过它。因此,如果我有一个子组件,例如...,我可以为 Cart 提供其中一个功能。这个函数会改变里面的状态不管是否还是mounted/shown.
如果您像那样重组您的应用程序,那么您可以执行以下操作:
App.js 添加一个函数来改变它的状态。
changeState(key, value){
this.setState({
key : value
}
}
现在将此函数作为 prop 传递
<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));
我正在尝试在两个页面之间切换,但是 运行 在学习过程中遇到很多问题 react router
在我的 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 Component,但是控制台打印:
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:如果我在 App
组件中更改了状态,当我从购物车 component
返回到 App
组件时,状态没有得到刷新。例如(例如,项目中的布尔值 "purchase"。)当我从购物车的 App 组件返回时,状态保持为真,相反,我希望它回到初始状态。
我按照教程进行操作,但它只是坏了。我做错了什么
所以警告是因为 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));
显然您还需要使用 ComponentDidMount
_isMounted
更改为 true
关于应用程序的状态不是 'refreshing'...这是因为当您从应用程序 > 购物车 > 应用程序进入时,应用程序组件永远不会卸载和再次安装。
要解决此问题,请使用 exact path="/"
switch
仅在 url 与主页完全匹配时安装 <App />
组件
<switch>
<div>
<Route exact path="/displayCart" component={Cart}/>
<Route exact path="/" component={App} />
</div>
</switch>
现在,如果您想跟踪状态变化,即使在 API 调用完成之前已关闭(卸载),那么您应该在 <App/>
中创建一个函数来执行 setState
并将其作为道具传递给 <Cart />
然后从内部您可以调用此道具功能。
这只有在你将 React Router 的东西放在
中时才有效我的做法是这样的: - index.js 始终加载 - 然后在我内部重定向到显示正确的组件
这意味着始终挂载。但是,它让我可以使用 App 的状态作为默认 "main" 状态,该状态始终存在,因为我从未卸载过它。因此,如果我有一个子组件,例如...,我可以为 Cart 提供其中一个功能。这个函数会改变里面的状态不管是否还是mounted/shown.
如果您像那样重组您的应用程序,那么您可以执行以下操作:
App.js 添加一个函数来改变它的状态。
changeState(key, value){
this.setState({
key : value
}
}
现在将此函数作为 prop 传递
<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));