Con*_*tes 79 reactjs react-router
我正在使用react-router处理反应应用程序.我有一个项目页面,其中包含如下网址:
myapplication.com/project/unique-project-id
Run Code Online (Sandbox Code Playgroud)
当项目组件加载时,我从componentDidMount事件触发该项目的数据请求.我现在遇到一个问题,如果我直接在两个项目之间切换,所以只有id改变这样......
myapplication.com/project/982378632
myapplication.com/project/782387223
myapplication.com/project/198731289
Run Code Online (Sandbox Code Playgroud)
componentDidMount不会再次触发,因此不会刷新数据.我应该使用另一个生命周期事件来触发我的数据请求,还是采用不同的策略来解决这个问题?
Bra*_*ugh 70
如果链接指向同一路线只有一个不同的参数,它不会重新安装,而是接收新的道具.所以,你可以使用该componentWillReceiveProps(newProps)
功能并寻找newProps.params.projectId
.
如果您正在尝试加载数据,我建议在路由器使用组件上的静态方法处理匹配之前获取数据.看看这个例子.反应路由器Mega演示.这样,组件将加载数据并在路径参数更改时自动更新,而无需依赖componentWillReceiveProps
.
Bre*_*t25 57
这是我的答案,类似于上面的一些但有代码.
<Route path="/page/:pageid" render={(props) => (
<Page key={props.match.params.pageid} {...props} />)
} />
Run Code Online (Sandbox Code Playgroud)
chi*_*lli 12
您必须清楚,路由更改不会导致页面刷新,您必须自己处理它.
import theThingsYouNeed from './whereYouFindThem'
export default class Project extends React.Component {
componentWillMount() {
this.state = {
id: this.props.router.params.id
}
// fire action to update redux project store
this.props.dispatch(fetchProject(this.props.router.params.id))
}
componentDidUpdate(prevProps, prevState) {
/**
* this is the initial render
* without a previous prop change
*/
if(prevProps == undefined) {
return false
}
/**
* new Project in town ?
*/
if (this.state.id != this.props.router.params.id) {
this.props.dispatch(fetchProject(this.props.router.params.id))
this.setState({id: this.props.router.params.id})
}
}
render() { <Project .../> }
}
Run Code Online (Sandbox Code Playgroud)
如果你有:
<Route
render={(props) => <Component {...props} />}
path="/project/:projectId/"
/>
Run Code Online (Sandbox Code Playgroud)
在React 16.8及更高版本中,使用hooks可以执行以下操作:
import React, { useEffect } from "react";
const Component = (props) => {
useEffect(() => {
props.fetchResource();
}, [props.match.params.projectId]);
return (<div>Layout</div>);
}
export default Component;
Run Code Online (Sandbox Code Playgroud)
在这里,fetchResource
只要有props.match.params.id
更改,您就只会触发一个新呼叫。
@wei 的回答很有效,但在某些情况下,我发现最好不要设置内部组件的键,而是设置路由本身。此外,如果组件的路径是静态的,但您只想在每次用户导航到它时重新安装组件(可能在 componentDidMount() 进行 api 调用),则将 location.pathname 设置为路由的键很方便。有了它,当位置改变时,它的路线和它的所有内容都会被重新安装。
const MainContent = ({location}) => (
<Switch>
<Route exact path='/projects' component={Tasks} key={location.pathname}/>
<Route exact path='/tasks' component={Projects} key={location.pathname}/>
</Switch>
);
export default withRouter(MainContent)
Run Code Online (Sandbox Code Playgroud)
小智 5
我是这样解决问题的:
此方法从 API 获取单个项目:
loadConstruction( id ) {
axios.get('/construction/' + id)
.then( construction => {
this.setState({ construction: construction.data })
})
.catch( error => {
console.log('error: ', error);
})
}
Run Code Online (Sandbox Code Playgroud)
我从 componentDidMount 调用这个方法,这个方法只会被调用一次,当我第一次加载这个路由时:
componentDidMount() {
const id = this.props.match.params.id;
this.loadConstruction( id )
}
Run Code Online (Sandbox Code Playgroud)
从第二次加载相同的路由但不同的 ID 开始调用 componentWillReceiveProps,我调用第一个方法重新加载状态,然后组件将加载新项目。
componentWillReceiveProps(nextProps) {
if (nextProps.match.params.id !== this.props.match.params.id) {
const id = nextProps.match.params.id
this.loadConstruction( id );
}
}
Run Code Online (Sandbox Code Playgroud)
根据@ wei,@ Breakpoint25和@PaulusLimma的回答,我为制作了此替换组件<Route>
。URL更改时,这将重新安装页面,迫使页面中的所有组件都被创建并重新安装,而不仅仅是重新呈现。所有componentDidMount()
其他所有启动挂钩也都在URL更改时执行。
这个想法是key
在URL更改时更改组件属性,这将迫使React重新安装组件。
您可以将其用作的替代产品<Route>
,例如:
<Router>
<Switch>
<RemountingRoute path="/item/:id" exact={true} component={ItemPage} />
<RemountingRoute path="/stuff/:id" exact={true} component={StuffPage} />
</Switch>
</Router>
Run Code Online (Sandbox Code Playgroud)
该<RemountingRoute>
组件的定义如下:
export const RemountingRoute = (props) => {
const {component, ...other} = props
const Component = component
return (
<Route {...other} render={p => <Component key={p.location.pathname + p.location.search}
history={p.history}
location={p.location}
match={p.match} />}
/>)
}
RemountingRoute.propsType = {
component: PropTypes.object.isRequired
}
Run Code Online (Sandbox Code Playgroud)
这已经通过React-Router 4.3进行了测试。
归档时间: |
|
查看次数: |
46903 次 |
最近记录: |