我有一条路线,它采用一个 id 并为每个 id 呈现相同的组件,例如:
<Route path='/:code' component={Card}/>
现在,在 Link 标签中,我将 id 传递给组件。现在,Card 组件根据传递的 id 获取其他详细信息。但问题是它仅针对一个 id 呈现,并且如果我单击“后退”并转到下一个 id,则不会更新。我搜索并发现 ComponentsWillReceiveProps 可以使用,但在最近版本的 React 中它已被弃用。那么如何做到这一点呢?
将当前位置作为组件的键解决了问题。
<Route path='/:code' component={(props) => <Card {...props} key={window.location.pathname}/>}/>
我刚刚遇到了类似的问题。我认为您正在将更新/重新渲染和重新安装混为一谈。 这个有关 React 生命周期方法的图表在我处理它时对我很有帮助。
如果你的问题和我的一样,那么你有一个像这样的组件
class Card extend Component {
componentDidMount() {
// call fetch function which probably updates your redux store
}
render () {
return // JSX or child component with {...this.props} used,
// some of which are taken from the store through mapStateToProps
}
}
第一次点击安装此组件的 URL 时,一切正常,然后,当您访问使用相同组件的另一个路由时,没有任何变化。那是因为组件没有被重新安装,它只是因为一些 props 改变而被更新,至少
this.props.match.params
正在改变。但是组件更新时不会调用
componentDidMount()
(请参阅上面的链接)。所以你不会获取新数据并更新你的 redux 存储。您应该添加一个
componentDidUpdate()
函数。这样你就可以在 props 改变时再次调用你的获取函数,而不仅仅是在组件最初安装时。
componentDidUpdate(prevProps) {
if (this.match.params.id !== prevProps.match.params.id) {
// call the fetch function again
}
}
查看反应
我们将从您的示例代码开始:
<Route path='/:code' component={Card}/>
<Card>
成为一个包装组件,最好是功能性的(它实际上不需要我认为不需要的任何状态),并通过使用传递你的 props 来渲染你想要渲染的组件
{...props}
,这样它就可以获取 Router 属性,但重要的是给它一个
key
属性,强制它从头开始重新渲染例如,我有一些看起来像这样的东西:
<Route exact={false} path="/:customerid/:courierid/:serviceid" component={Prices} />
我希望我的组件在 URL 更改时重新呈现,但仅限于 customerid 或 serviceid 更改时。所以我把
Prices
做成了这样的功能组件:
function Prices (props) {
const matchParams = props.match.params;
const k = `${matchParams.customerid}-${matchParams.serviceid}`;
console.log('render key (functional):');
console.log(k);
return (
<RealPrices {...props} key={k} />
)
}
请注意,我的密钥仅考虑 customerid 和 serviceid - 当这两个更改时它会重新渲染,但当 courierid 更改时它不会重新渲染(如果您愿意,只需将其添加到密钥中即可)。我的
RealPrices
组件的好处是仍然可以传递所有路线道具,例如历史记录、位置、匹配等。
如果您要从某些 API 获取数据,那么您可以将该调用包装在
useEffect
块内,并将
history.location.pathname
作为参数传递给
useEffect
。代码:
import { useHistory } from "react-router";
const App = () => {
const history = useHistory();
useEffect(() => {
//your api call here
}, [history.location.pathname]);
};
来自
useHistory
的
react-router
钩子将给出路径名称,因此每次更改
useEffect
时都会调用它(url)
import { useHistory } from "react-router";
const App = () => {
const history = useHistory();
useEffect(() => {
// do you task here
}, [history.location.href]);
};
import {useLocation} from "react-router-dom";
export default function Card() {
const location = useLocation();
useEffect(()=>{}, [location]);
return(
// your code here
);
}
Switch
标签后添加
Router
标签修复了问题 像这样
<Router>
<Switch>
</Switch>
</Router>