同一组件上的链接不刷新页面 [英] Link on same component not resfresh page

查看:44
本文介绍了同一组件上的链接不刷新页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 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钩子

的匹配参数访问id

const { 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]);

这篇关于同一组件上的链接不刷新页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆