我有两个获取示例组件的链接,但是当我单击其中任何一个链接时,它会被加载,而当我单击另一个链接时,它不会重新呈现,只有 url 被更改。我想在两次链接点击时重新渲染组件。有没有办法做到这一点?
在 url 更改时我想重新呈现我的组件我应该怎么做
当我在做一个 React 项目时,我曾经遇到过类似的问题。
您需要在组件中使用componentWillReceiveProps函数。
componentWillReceiveProps(nextProps){
//call your api and update state with new props
}
更新
对于react版本 16.3+,请使用 componentDidUpdate
componentDidUpdate (prevProps, prevState) {
// update state
}
通过调用 url www.example.com/content/acomponentDidMount()
运行,以便在您的组件第一次加载时更清楚 。
现在,当您单击另一个链接时,说 www.example.com/content/b 调用了相同的组件,但这次 prop 发生了变化,您可以访问这个新的 prop componentWillReceiveProps(nextProps)
,您可以使用它来调用 api 并获取新数据。
现在你可以保留一个通用函数 sayinitializeComponent()
并从componentDidMount()
and调用它componentWillReceiveProps()
你的路由器看起来像这样:-
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/content" component={app}>
<IndexRoute component={home}/>
<Route path="/content/:slug" component={component_name} />
</Route>
</Router>
), document.getElementById('app'));
所以现在当您调用 www.example.com/content/a 时,a将被视为 slug。在该组件中,如果您调用 www.example.com/content/b ,则b将被视为 slug 并且可用作 componentWillReceiveProps 中的 nextProps 参数。
希望能帮助到你!!
使用定位钩。
const location = useLocation();
const renderDOM = () => {
// return your DOM, e.g. <p>hello</p>
}
useEffect(() => {
// re render your component
renderDOM();
},[location]);
return (
<>
{renderDOM()}
</>
);
我自己使用这样的纯函数组件也遇到了同样的问题:
import { useHistory, Link, BrowserRouter, useLocation } from 'react-router-dom'
function Comp() {
const history = useHistory()
// useLocation()
return (
<>
<p>current path is {history.location.pathname}</p>
<Link to="/abc">click me</Link>
<Link to="/xyz">click me</Link>
</>
)
}
export default function App() {
return (
<BrowserRouter>
<Comp />
</BrowserRouter>
)
}
当您单击链接时,标题栏中的 URL 会更新,但组件不会重新呈现(即显示的路径不会更新)
在这种情况下,我发现解决方案是包含对useLocation()
(显示已注释掉)的调用。你甚至不需要对返回值做任何事情;添加此调用会使组件在位置更改时神奇地重新渲染。
请注意,这是使用 react-router 5.3。react-router 6 被改得面目全非,所以我不知道同样的问题是否仍然存在
React 16.3+不鼓励使用componentWillReceiveProps
.
React 现在建议将数据更新移动到componentDidUpdate
( source ):
// After
class ExampleComponent extends React.Component {
state = {
externalData: null,
};
static getDerivedStateFromProps(props, state) {
// Store prevId in state so we can compare when props change.
// Clear out previously-loaded data (so we don't render stale stuff).
if (props.id !== state.prevId) {
return {
externalData: null,
prevId: props.id,
};
}
// No state update necessary
return null;
}
componentDidMount() {
this._loadAsyncData(this.props.id);
}
componentDidUpdate(prevProps, prevState) {
if (this.state.externalData === null) {
this._loadAsyncData(this.props.id);
}
}
componentWillUnmount() {
if (this._asyncRequest) {
this._asyncRequest.cancel();
}
}
render() {
if (this.state.externalData === null) {
// Render loading state ...
} else {
// Render real UI ...
}
}
_loadAsyncData(id) {
this._asyncRequest = loadMyAsyncData(id).then(
externalData => {
this._asyncRequest = null;
this.setState({externalData});
}
);
}
}