![the the](https://c1.lmlphp.com/image/static/default_avatar.gif)
本文介绍了同一组件上的链接不刷新页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个带有 ID 的页面,如果我通过链接 https://localhost 转到同一页面:8443/news/10 使用另一个 ID 页面不会更新 props 和 state,并且页面看起来与刷新之前完全相同.我认为这是因为我没有更改 redux 中的 state 和 props.
新闻页面项
import React, { useEffect } from 'react';import { Link, useHistory } from 'react-router-dom';从'./../shared/Comments/Comments'导入评论;从'common/Container/Container'导入容器;从'../../shared/NewsItem/NewsItem'导入新闻项目;从'../../../models/entity/NewEntity'导入NewEntity;从'common/Svg'导入Svg;从 './author.png' 导入 ava;从'../img.png'导入bg;导入'./NewsPageItem.scss';从'react-redux'导入{shallowEqual,useDispatch,useSelector};进口 {得到评论,获取列表,获取新 ID,newsByIdSelector,新闻评论选择器,新闻列表选择器,发送评论,设置喜欢,设置视图,来自鸭子/新闻";从共享/滑动/滑动"导入滑动;const NewsPageItem:React.FC = () =>{const 历史 = useHistory();const dispatch = useDispatch();const newById = useSelector(newsByIdSelector,shallowEqual);const 评论 = useSelector(newsCommentsSelector,shallowEqual);让新闻 = useSelector(newsListSelector,shallowEqual);const id = history.location.pathname.split('/')[2];控制台日志(ID);const { likes_count, views_count } = newById;news = news.filter((elem: any) => elem.id !== Number(id));useEffect(() => {调度(getNewId(id));调度(getList());调度(setView(id));dispatch(getComments(id));}, [newById.likes_count, newById.views_count]);const handleLike = () =>{调度(setLike(id));};const sendMsg = (text: string) =>{dispatch(sentComment(id, text));};控制台日志(444);返回 (<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"/></链接><div className="news__wrap"><div className="news__title">Технические работы на нашем сайте</div><div className="news__author"><div className="news__author--img"><img src={ava} alt="Алёна Малюченко"/>
<div className="news__author--info"><div className="news__author--name">Алёна Малюченко</div><div className="news__author--cat">Автор новости</div>
<div className="news__stats"><div className="news__icon"><Svg name="calendar" width={15} height={16} className="news__svg"/>15 декабря
<div className="news__icon"><Svg name="info" width={16} height={16} className="news__svg"/>Новость
<div className="news__icon"><Svg name="time" width={10} height={16} className="news__svg"/>2 мин.
<div className="news__content content"><容器><h3>Заголовок новости</h3><p>Практический опыт показывает, что консультация с профессионалами из IT создаёт предпосылкикачественно новых шагов для модели развития?Разнообразный и богатый опыт курс насоциально-ориентированный национальный проект способствует подготовке и реализациисоответствующих условий активизации.Равным образом консультация с профессионалами из IT требуетопределения и уточнения дальнейших направлений развитая системы массового участия.</p><p>Таким образом, повышение уровня гражданского сознания позволяет оценить значение всестороннесбалансированных нововедений.Задача организации, в особенности же начало повседневной работыпо формированию позиции способствует подготовке и реализации дальнейших направлений развитаясистемы массового участия.Дорогие друзья, постоянный количественный рост и сфера нашейактивности создаёт предпосылки качественно новых шагов для системы обучения кадров,соответствующей насущным потребностям.С другой стороны начало повседневной работы поформированию позиции обеспечивает широкому кругу специалистов участие в формировании систеобучения кадров, соответствующей насущным потребностям!</p><div className="news__info">«Не следует, однако, забывать о том, что рамки и место обучения кадров напрямую зависит отнаправлений прогрессивного развития»
<h3>Значимость этих проблем настолько очевидна:</h3><ul><li>Реализация намеченного плана развития влечет за собой процесс внедрения</li><li>Модернизации существующих финансовых и административных условий</li><li>Значимость этих проблем настолько очевидна</li><div className="news__stats"><div className="news__icon" onClick={handleLike}><Svg name="heart" width={24} height={24} className="news__svg"/>{likes_count}
<div className="news__icon"><Svg name="comment" width={20} height={20} className="news__svg"/>15
<div className="news__icon"><Svg name="view" width={20} height={20} className="news__svg"/>{views_count}
</容器>
<div className="other__news"><div className="other__wrap"><滑动标题={'Другие новости'} link="/news"><div className="mobile-page--history">{news.map((item, key) => (<NewsItem key={key} item={item as NewEntity} classname="other__item"/>))}
</滑动>
<容器><评论comments={comments} sendMsg={sendMsg}/></容器>
);};导出默认的 NewsPageItem;
新闻项目
从'react'导入React;从'react-router-dom'导入{链接};从'common/Svg'导入Svg;从'../../../models/entity/NewEntity'导入NewEntity;导入'./NewsItem.scss';导出接口 NewsItemShema {项目:新实体;类名?:字符串;}const NewsItem: React.FC= ({ 项目,类名 }) =>{const { id, file_url, start_at, title, text, likes_count, comments_count, views_count } = item;const 类名 = 类名 ?'news__item' + 类名:'news__item';const resizeText = (str: string | undefined) =>{if (str === undefined) 返回假;const txt = str.substring(0, 75);//eslint-disable-next-line 无控制台返回txt;};返回 (<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 className="news__icon"><Svg name="comment" width={20} height={20} className="news__svg"/>{comments_count}
<div className="news__icon"><Svg name="view" width={20} height={20} className="news__svg"/>{views_count}
</链接>);};导出默认新闻项目;
解决方案
如果你使用 Route 参数配置你的路由,你就不需要使用 history.location 并拆分它来获取值
你可以简单地配置你的路线
并使用带有useParams
钩子
的匹配参数访问idconst { id } = useParams();
现在您必须知道,当 Route params 更改时,组件不会重新安装而是重新渲染,因此您需要重新获取新 ID 的数据.为此,添加 id
作为 useEffect
的依赖项useEffect(() => {调度(getNewId(id));调度(getList());调度(setView(id));dispatch(getComments(id));}, [newById.likes_count, newById.views_count, id]);
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;
解决方案
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]);
这篇关于同一组件上的链接不刷新页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
07-17 13:40