gpt4 book ai didi

javascript - React Router 在重定向到具有不同 slug 的同一页面时触发重新加载/重新安装组件

转载 作者:行者123 更新时间:2023-11-29 10:56:43 26 4
gpt4 key购买 nike

我有一个使用 React (v.16.8.6)HashRouter(使用哈希路由器的要求)的演示应用程序。我的应用程序只是获取一些天气数据并显示某些城市天气的相关组件。

问题是索引页有搜索功能,搜索页也有类似的功能。当给出搜索词时,应用会重定向到 #/search/{term} 路由。一切都按预期工作,但是当我已经在搜索页面上并触发新搜索时,我重定向到具有不同 {term} slug 的同一搜索页面(需要更新浏览器当前 url,包括哈希)。

因此,页面不会重新加载,组件也不会重新挂载,因此不会触发生命周期 Hook (尤其是进行设置的 componentDidMount)。

我做了一个模拟组件重新加载的解决方法,但它有点像 hack(例如直接操作状态和设置超时,请参见下面的相关代码)。

在正确重新加载/重新挂载组件时,是否有更好的方法来实现重定向到同一页面(并更改浏览器 url 包括哈希)?

App.js

import React, { Component } from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';

import HomePage from './home';
import SearchPage from './search';
import WeatherPage from './weather';

import './App.css';

class App extends Component {
render() {
return (
<HashRouter basename="/" hashType="slash">
<Switch>
<Route exact path={'/'} component={HomePage}></Route>
<Route path={'/weather/:woeid'} component={WeatherPage}></Route>
<Route path={'/search/:term'} component={SearchPage}></Route>
</Switch>
</HashRouter>
);
}
}

export default App;

SearchPage.js 组件

import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import Weather from '../components/Weather';

function fetchData( term ) {
return fetch('{api_url_here}?keyword='+term)
.then(response => response.json());
}

class SearchPage extends Component {
constructor(props){
super(props);
this.state = {
loading: true,
text: this.props.match.params.term,
redirect: false,
data: null
};
}

componentDidMount() {
fetchData(this.props.match.params.term).then(jsonResponse => {
this.setState({
loading: false,
data: jsonResponse
});
});
}

handleOnClick = () => {
this.setState({redirect: true});
}

handleInput = (evt) => {
this.setState({text: evt.target.value});
}

render() {
// any way to avoid this workaround while redirecting to same page?
// [from here]
if (this.state.redirect) {
this.state.redirect = false;
this.state.text = this.state.text.toLowerCase();
this.state.data = null;
this.state.loading = true;
// simulate componentDidMount, since it os not re-called on same page
setTimeout(()=>(fetchData(this.state.text).then(jsonResponse => {
this.setState({
loading: false,
data: jsonResponse
});
})), 40);
// redirect and update url
return <Redirect to={"/search/"+this.state.text} />;
// [to here]
}
return (
<div>
<h1>Search Page</h1>
<div>
<input type="text" placeholder="search.." value={this.state.text} onChange={this.handleInput} />
<button type="button" onClick={this.handleOnClick}>Search!</button>
</div>
{this.state.loading ? 'Loading..' : (this.state.data && this.state.data.length ? this.state.data.map(res => (<Weather woeid={res.woeid} city={res.title} />)) : 'No results found!')}
</div>
);
}
}

export default SearchPage;

基于重定向的解决方案(将重新加载/重新挂载组件)( Tholle's answer )

App 更改为以下内容:

class App extends Component {
render() {
return (
<HashRouter basename="/" hashType="slash">
<Switch>
<Route exact path={'/'} component={HomePage}></Route>
<Route path={'/weather/:woeid'} component={WeatherPage}></Route>
<Route path={'/search/:term'} render={props => <SearchPage key={props.match.params.term.toLowerCase()} {...props} />}></Route>
</Switch>
</HashRouter>
);
}
}

SearchPage 更改为以下内容:

class SearchPage extends Component {
constructor(props){
super(props);
this.state = {
loading: true,
text: this.props.match.params.term,
redirect: false,
data: null
};
}

componentDidMount() {
fetchData(this.props.match.params.term).then(jsonResponse => {
this.setState({
loading: false,
data: jsonResponse
});
});
}

handleOnClick = () => {
this.setState({redirect: true});
}

handleInput = (evt) => {
this.setState({text: evt.target.value});
}

render() {
if (this.state.redirect) {
// redirect and update url
return <Redirect to={"/search/"+this.state.text.toLowerCase()} />;
}
return (
<div>
<h1>Search Page</h1>
<div>
<input type="text" placeholder="search.." value={this.state.text} onChange={this.handleInput} />
<button type="button" onClick={this.handleOnClick}>Search!</button>
</div>
{this.state.loading ? 'Loading..' : (this.state.data && this.state.data.length ? this.state.data.map(res => (<Weather woeid={res.woeid} city={res.title} />)) : 'No results found!')}
</div>
);
}
}

最佳答案

一种解决方法是添加 componentDidUpdate SearchPage 的生命周期 Hook 组件并检查是否 term参数改变,重新搜索。

如果要在 term 时重新挂载组件参数更改,您可以使用 keykey 时卸载前一个组件并安装一个新组件。变化。

<Route
path={"/search/:term"}
render={props => <SearchPage key={props.match.params.term} {...props} />}
/>

关于javascript - React Router 在重定向到具有不同 slug 的同一页面时触发重新加载/重新安装组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55686610/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com