Я использую реагирующий маршрутизатор v4, возникла проблема с перезагрузкой страницы (не window.location.reload). Я лучше приведу реальный вариант использования, чтобы объяснить проблему, мы используем приложение социальной сети в качестве примера:
this.props.history.push('/job/' + id'), это сработало, следовательно, пользователь B перешел на страницу job/123.job/123, он щелкнул ссылку уведомления и запустил this.props.history.push('/job' + id'). Но он не увидит повторную визуализацию страницы, он НЕ видел последний комментарий, потому что страница ничего не делает.@AndrewLohr мне сложно реплицировать, поскольку я использую websocket, уведомление в реальном времени было отправлено от пользователя A к пользователю B, поэтому есть вероятность, что пользователь B щелкнет новое уведомление по тому же пути.
Я думаю, ваша проблема заключается в том, что вы нажимаете слишком один и тот же маршрут, и ваш компонент не обновляется после нажатия. postId не отличается от страниц /notification? postId - 123 на обеих страницах?
@soroushchehresa Я думаю, что использование /notification/postId сбивает людей с толку, я изменил его на задание, каждая деталь задания имеет комментарий, уведомление предназначено только для того, чтобы сообщить пользователю, что на указанной странице вакансии появилось новое уведомление.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы должны посмотреть обновление postId в жизненном цикле componentWillUpdate и сделать что-нибудь отсюда вроде этого:
componentWillUpdate(np) {
const { match } = this.props;
const prevPostId = match.params.postId;
const nextPostId = np.match.params.postId;
if (nextPostId && prevPostId !== nextPostId){
// do something
}
}
componentWillUpdate - это не «здоровый» метод жизненного цикла, я полагаю? Он устарел в React 16. Кстати, postId всегда будет таким же, потому что многие уведомления указывают на один и тот же пост.
Правильно, вместо этого вы должны выполнить аналогичную проверку в componentDidUpdate (). Этот ответ может быть полезным.
но как здесь работает логика? nextPostId и prevPostId всегда будут одинаковыми
@Hoknimo При использовании componentWillUpdate с условиями это может быть здоровым методом жизненного цикла!
@Hoknimo При нажатии на / уведомление с новым postId на странице уведомления nextPostId будет обновлен до нового postId с URL-адреса.
@Hoknimo Например: от / notification / 123 до / notification / 456
Вы описываете 2 различных типа изменений состояния.
В первом сценарии, когда пользователь B является нет на странице /job/:id и щелкает ссылку, вы получаете изменение URL-адреса, которое запускает изменение состояния в маршрутизаторе и распространяет это изменение на ваш компонент, чтобы вы могли видеть комментарий.
Во втором сценарии, когда пользователь B является уже в, страница /job/:id и приходит новый комментарий, URL-адрес не нужно менять, поэтому нажатие на ссылку не изменит URL-адрес и не вызовет изменение состояния в маршрутизатор, поэтому вы не увидите новый контент.
Я бы, наверное, попробовал что-то вроде этого (псевдокод, потому что я не знаю, как вы получаете новые комментарии или подписываетесь через веб-сокет):
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
class Home extends React.Component {
render() {
return (
<div>
<h1>The home page</h1>
{/* This is the link that the user sees when someone makes a new comment */}
<Link to = "/job/123">See the new comment!</Link>
</div>
);
}
}
class Job extends React.Component {
state = { comments: [] };
fetchComments() {
// Fetch the comments for this job from the server,
// using the id from the URL.
fetchTheComments(this.props.params.id, comments => {
this.setState({ comments });
});
}
componentDidMount() {
// Fetch the comments once when we first mount.
this.fetchComments();
// Setup a listener (websocket) to listen for more comments. When
// we get a notification, re-fetch the comments.
listenForNotifications(() => {
this.fetchComments();
});
}
render() {
return (
<div>
<h1>Job {this.props.params.id}</h1>
<ul>
{this.state.comments.map(comment => (
<li key = {comment.id}>{comment.text}</li>
))}
</ul>
</div>
);
}
}
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route exact path = "/" component = {Home} />
<Route path = "/job/:id" component = {Job} />
</Switch>
</BrowserRouter>,
document.getElementById("app")
);
Теперь страница будет обновляться в обоих сценариях.
Во многих случаях это кажется обычным сценарием. С ней можно справиться, используя множество различных подходов. Отметьте это вопрос о переполнении стека. Есть несколько хороших ответов и выводов. Лично для меня этот подход имел больше смысла.
location.key изменяется каждый раз, когда пользователь пытается перемещаться между страницами, даже в пределах одного и того же route. Чтобы проверить это место ниже блока кода в вашем компоненте /jod/:id:
componentDidUpdate (prevProps) {
if (prevProps.location.key !== this.props.location.key) {
console.info("... prevProps.key", prevProps.location.key)
console.info("... this.props.key", this.props.location.key)
}
}
У меня была точно такая же ситуация. Обновленное состояние в componentDidUpdate. После этого заработало как положено. Нажатие на элементы в пределах одного маршрута обновляет состояние и отображает правильную информацию.
Я предполагаю (поскольку не уверен, как вы передаете / обновляете комментарии в /job/:id), если вы установите что-то подобное в своем компоненте /job/:id, должно работать:
componentDidUpdate (prevProps) {
if (prevProps.location.key !== this.props.location.key) {
this.setState({
comments: (((this.props || {}).location || {}).comments || {})
})
}
}
это решило проблему для меня:
import { BrowserRouter as Router,Route,Switch,Redirect} from "react-router-dom";
<Router>
<Switch>
<Redirect from = "/x_walls/:user_Id" to='/walls/:user_Id'/>
<Route path = "/walls/:user_Id" exact render = {(props) => <Wall {...props}/> }/>
</Switch>
</Router>
и когда вы хотите назвать "стены", вы просто вызываете "x_walls" вместо этого
это хорошее объяснение, но было бы лучше увидеть ваш код, имеющий отношение к этой проблеме, иначе вам было бы очень трудно помочь.