Link on same component not resfresh page

强颜欢笑 提交于 2021-01-29 22:00:00

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!