1

as you can see here i get some news from an api that is in another component named cts and then i want to render it and show the full content when the user click on one of them. just for testing i use SS component here.
the problem is that i want to use history.push to navigate to path of news items but it doesn't work the problem that confuse me that is when i use Link for navigating it works truly

please help me i really don't know what should i do and it's two days that im working on it

import React, { useState, useEffect } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
  useHistory,
  Link,
  useRouteMatch,
  useParams
} from 'react-router-dom';
import styled from 'styled-components';
import apis from '../../app/apis';
import cts from '../../app/cts';
import NewsFullContent from './components/NewsFullContent';

// Styles
const NewsBox = styled.div`
  margin: 20px 0 20px 0;
  cursor: pointer
`;

const NewsTitle = styled.h1`
  font-size: 14pt;
`;

const NewsDate = styled.h3`
  font-size: 10pt;
  color: #aaa;
`;

const News = (props) => {

  // Hooks
  const history = useHistory();
  const [news, setNews] = useState(null);
  const [jsonNews, setJsonNews] = useState(null);
  const match = useRouteMatch();
  const { id } = useParams();

  useEffect(() => {
    getNews('556', '556');
  }, [news]);

  // Getting News api
  const getNews = async (project, district) => {

    try {
      const { data, status } = await cts('get', apis.getNewsApi(project, district));
      if (status !== 200 && !data) {
        throw new Error('Error fetching data');
      } else {
        const newsList = Object.values(data.items).map((item) => (
          <div>
            <Link to={`${match.path}/${item.id}`}>
              <NewsTitle>
                {item.title}
              </NewsTitle>
            </Link>
            <NewsBox onClick={() => history.push(`${match.path}/${item.id}`)}>
              <NewsTitle>
                {item.title}
              </NewsTitle>
              <NewsDate>
                {item.date}
              </NewsDate>
            </NewsBox>
          </div>
        ));
        setNews(newsList);
        setJsonNews(data);
      }
    } catch (e) {
      throw new Error('Error rendering data');
    }
  };

  const SS = () => {
    setNews(null);
    return (
      <div>
        component is Open
      </div>
    );
  };

  return (
    <Router>
      {
        news
      }
      <Switch>
        <Route path={`${match.path}/:id`}>
          <SS />
        </Route>
      </Switch>
    </Router>
  );
};

export default News;

watch the output here:
the first item i click is working with Link
and the second one is working with history.pushenter image description here

  • Why do you want to use `onClick` rather than an actual `a`nchor element? You either have to reimplement all of the standard behaviour or end up with something that's not accessible. – jonrsharpe Oct 13 '20 at 11:02

2 Answers2

0

You can change you styled component to following:

const NewsBox = styled(Link)`
  ...
`

and then pass to props to NewsBook

<NewsBox to={`${match.path}/${item.id}`}>
 ...
<NewsBox />

Punit Makwana
  • 485
  • 1
  • 6
  • 13
0

The only way to use history api is by using withRouter higher order component like this :

import { withRouter } from 'react-router-dom'

const News = ( { history } ) => {

 return (
   <button onClick={ () => history.push("/")}> Push / to url </button>
 )

}

export default withRouter(News)
Mehdi Faraji
  • 2,574
  • 8
  • 28
  • 76