问题
I have a page with ID, if I go to the same page through the Link https://localhost:8443/news/10 with another ID the page does not update props and state, and the page looks exactly the same as it was before you refresh it. I think this is because I do not change the state and props in the redux.
NewsPageItem
import React, { useEffect } from 'react';
import { Link, useHistory } from 'react-router-dom';
import Comments from './../shared/Comments/Comments';
import Container from 'common/Container/Container';
import NewsItem from '../../shared/NewsItem/NewsItem';
import NewEntity from '../../../models/entity/NewEntity';
import Svg from 'common/Svg';
import ava from './author.png';
import bg from '../img.png';
import './NewsPageItem.scss';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import {
getComments,
getList,
getNewId,
newsByIdSelector,
newsCommentsSelector,
newsListSelector,
sentComment,
setLike,
setView,
} from 'ducks/news';
import Swipe from 'shared/Swipe/Swipe';
const NewsPageItem: React.FC = () => {
const history = useHistory();
const dispatch = useDispatch();
const newById = useSelector(newsByIdSelector, shallowEqual);
const comments = useSelector(newsCommentsSelector, shallowEqual);
let news = useSelector(newsListSelector, shallowEqual);
const id = history.location.pathname.split('/')[2];
console.log(id);
const { likes_count, views_count } = newById;
news = news.filter((elem: any) => elem.id !== Number(id));
useEffect(() => {
dispatch(getNewId(id));
dispatch(getList());
dispatch(setView(id));
dispatch(getComments(id));
}, [newById.likes_count, newById.views_count]);
const handleLike = () => {
dispatch(setLike(id));
};
const sendMsg = (text: string) => {
dispatch(sentComment(id, text));
};
console.log(444);
return (
<div className="news__page">
<div className="news__header" style={{ backgroundImage: `url(${bg})` }}>
<Link to="/news" className="news__back">
<Svg name="arrow_back" width={26} height={20} className="news__svg" />
</Link>
<div className="news__wrap">
<div className="news__title">Технические работы на нашем сайте</div>
<div className="news__author">
<div className="news__author--img">
<img src={ava} alt="Алёна Малюченко" />
</div>
<div className="news__author--info">
<div className="news__author--name">Алёна Малюченко</div>
<div className="news__author--cat">Автор новости</div>
</div>
</div>
<div className="news__stats">
<div className="news__icon">
<Svg name="calendar" width={15} height={16} className="news__svg" />
15 декабря
</div>
<div className="news__icon">
<Svg name="info" width={16} height={16} className="news__svg" />
Новость
</div>
<div className="news__icon">
<Svg name="time" width={10} height={16} className="news__svg" />2 мин.
</div>
</div>
</div>
</div>
<div className="news__content content">
<Container>
<h3>Заголовок новости</h3>
<p>
Практический опыт показывает, что консультация с профессионалами из IT создаёт предпосылки
качественно новых шагов для модели развития? Разнообразный и богатый опыт курс на
социально-ориентированный национальный проект способствует подготовке и реализации
соответствующих условий активизации. Равным образом консультация с профессионалами из IT требует
определения и уточнения дальнейших направлений развитая системы массового участия.
</p>
<p>
Таким образом, повышение уровня гражданского сознания позволяет оценить значение всесторонне
сбалансированных нововведений. Задача организации, в особенности же начало повседневной работы
по формированию позиции способствует подготовке и реализации дальнейших направлений развитая
системы массового участия. Дорогие друзья, постоянный количественный рост и сфера нашей
активности создаёт предпосылки качественно новых шагов для системы обучения кадров,
соответствующей насущным потребностям. С другой стороны начало повседневной работы по
формированию позиции обеспечивает широкому кругу специалистов участие в формировании системы
обучения кадров, соответствующей насущным потребностям!
</p>
<div className="news__info">
«Не следует, однако, забывать о том, что рамки и место обучения кадров напрямую зависит от
направлений прогрессивного развития»
</div>
<h3>Значимость этих проблем настолько очевидна:</h3>
<ul>
<li>Реализация намеченного плана развития влечет за собой процесс внедрения</li>
<li>Модернизации существующих финансовых и административных условий</li>
<li>Значимость этих проблем настолько очевидна</li>
</ul>
<div className="news__stats">
<div className="news__icon" onClick={handleLike}>
<Svg name="heart" width={24} height={24} className="news__svg" />
{likes_count}
</div>
<div className="news__icon">
<Svg name="comment" width={20} height={20} className="news__svg" />
15
</div>
<div className="news__icon">
<Svg name="view" width={20} height={20} className="news__svg" />
{views_count}
</div>
</div>
</Container>
</div>
<div className="other__news">
<div className="other__wrap">
<Swipe title={'Другие новости'} link="/news">
<div className="mobile-page--history">
{news.map((item, key) => (
<NewsItem key={key} item={item as NewEntity} classname="other__item" />
))}
</div>
</Swipe>
</div>
</div>
<Container>
<Comments comments={comments} sendMsg={sendMsg} />
</Container>
</div>
);
};
export default NewsPageItem;
NewsItem
import React from 'react';
import { Link } from 'react-router-dom';
import Svg from 'common/Svg';
import NewEntity from '../../../models/entity/NewEntity';
import './NewsItem.scss';
export interface NewsItemShema {
item: NewEntity;
classname?: string;
}
const NewsItem: React.FC<NewsItemShema> = ({ item, classname }) => {
const { id, file_url, start_at, title, text, likes_count, comments_count, views_count } = item;
const classnames = classname ? 'news__item ' + classname : 'news__item ';
const resizeText = (str: string | undefined) => {
if (str === undefined) return false;
const txt = str.substring(0, 75);
// eslint-disable-next-line no-console
return txt;
};
return (
<Link to={`/news/${id}`} className={classnames} style={{ backgroundImage: `url(${file_url})` }}>
<div className="news__wrap">
<div className="news__date">{start_at}</div>
<div className="news__title">{title}</div>
<div className="news__desc">{resizeText(text) + '...'}</div>
<div className="news__stats">
<div className="news__icon">
<Svg name="heart" width={24} height={24} className="news__svg" />
{likes_count}
</div>
<div className="news__icon">
<Svg name="comment" width={20} height={20} className="news__svg" />
{comments_count}
</div>
<div className="news__icon">
<Svg name="view" width={20} height={20} className="news__svg" />
{views_count}
</div>
</div>
</div>
</Link>
);
};
export default NewsItem;
回答1:
If you configure your route with a Route param, you do not need to use history.location and split it to get the value
you can simply configure your Route like
<Route path="/news/:id" component={NewsPageItem} />
and access the id using match params with useParams
hook
const { id } = useParams();
Now you must know that when Route params change the component is not remounted but re-renderd and hence you would need to refetch the data for new id. To do that add id
as a dependency to useEffect
useEffect(() => {
dispatch(getNewId(id));
dispatch(getList());
dispatch(setView(id));
dispatch(getComments(id));
}, [newById.likes_count, newById.views_count, id]);
来源:https://stackoverflow.com/questions/61803740/link-on-same-component-not-resfresh-page