Реагирующие крючки, открывающие содержимое статей при нажатии кнопки или ссылки

#reactjs #api #react-hooks #feed

#reactjs #API #реагирующие хуки #лента

Вопрос:

Я работаю над новостным веб-приложением в React.js и я пытаюсь выяснить, как перенаправить пользователя на страницу другого компонента, содержащую дополнительную информацию о статье, на которую они нажали. Я много чего перепробовал, но я довольно заблудился. Я создал перехват, который извлекает данные из URL-ссылки с заданными данными новостной статьи.

 import { useState, useEffect } from 'react';

export const useHttp = (url, dependencies) => {
  const [isLoading, setIsLoading] = useState(false);
  const [fetchedData, setFetchedData] = useState(null);

  useEffect(() => {
      setIsLoading(true);
      console.log('Sending Http request');
      fetch(url)
      .then(res => {
         if (!res.ok) {
             throw new Error('Failed to fetch');
         }
         return res.json();
        
      })
      .then(data => {
        console.log(data);
        setIsLoading(false);
        setFetchedData(data); //something here
      })
      .catch(err => {
        console.log(err);
        setIsLoading(false);
      });
      // eslint-disable-next-line
  }, dependencies);

  return [isLoading, fetchedData];
};
  

У меня есть несколько компонентов с очень похожей функциональностью, которые используют этот хук для захвата всех статей с URL-адреса, относящегося к этому компоненту, и сопоставляют его данные для получения значений, которые позже сопоставляются для заполнения компонента card, который вызывается во всех этих других компонентах, так что новостные статьи отображаются на просматриваемой в данный момент странице. Вот компонент для новостей науки.

 import React from 'react';
import { Spinner, CardDeck } from 'react-bootstrap';
import { CardElement } from './Card';
import { useHttp } from '../hooks/http';

const sciUrl = 'http://newsapi.org/v2/top-headlines?country=usamp;category=scienceamp;apiKey=60d859683c7d4ae68160e82bcc4d39ea';

export const SciNews = () => {
  const [isLoading, fetchedData] = useHttp(sciUrl, []);

  // const classes = useStyles();
  const sciNews = fetchedData
    ? fetchedData.articles.map((article, index) => ({
        image: article.urlToImage,
        name: article.source.name,
        title: article.title,
        description: article.description,
        id: index,
      }))
    : [];

  let content = <Spinner animation="grow" />;

  if (!isLoading amp;amp; sciNews amp;amp; sciNews.length > 0) {
    content = (
      <div>
        {sciNews.map((article) => (
          <CardElement key={article.id} article={article} />
        ))}
      </div>
    );
  } else if (!isLoading amp;amp; (!sciNews || sciNews.length === 0)) {
    content = <p>Could not fetch any data.</p>;
  }
  return content;
};

const sciHomeUrl = 'http://newsapi.org/v2/top-headlines?country=usamp;category=scienceamp;pageSize=3amp;sortBy=popularityamp;apiKey=60d859683c7d4ae68160e82bcc4d39ea';

export const SciHomeNews = () => {
  const [isLoading, fetchedData] = useHttp(sciHomeUrl, []);

  // const classes = useStyles();
  const sciHomeNews = fetchedData
    ? fetchedData.articles.map((article, index) => ({
        image: article.urlToImage,
        name: article.source.name,
        title: article.title,
        description: article.description,
        id: index,
      }))
    : [];

  let content = <Spinner animation="grow" />;

  if (!isLoading amp;amp; sciHomeNews amp;amp; sciHomeNews.length > 0) {
    content = (
      <CardDeck  style={{paddingLeft: "5%", paddingRight: "5%"}}>
        {sciHomeNews.map((article) => (
          <CardElement key={article.id} article={article} />
        ))}
      </CardDeck>
    );
  } else if (!isLoading amp;amp; (!sciHomeNews || sciHomeNews.length === 0)) {
    content = <p>Could not fetch any data.</p>;
  }
  return content;
};
  
  

Вот компонент Card..

 import React from 'react';
import { Card, Button } from 'react-bootstrap';

export const CardElement = ({ article }) => (

    <Card
      style={{ height: '75vh' }}
      key={article.id}
      bg="dark"
      text="white"
      className="my-3"
    >
      <Card.Img style={{ height: '50%' }} variant="top" src={article.image} />
      <Card.Body>
        <Card.Text>{article.name}</Card.Text>
        <Card.Title>{article.title}</Card.Title>
        <Card.Text>{article.description}</Card.Text>
        
      </Card.Body>
    </Card>
);
  

Как я могу добавить кнопку или ссылку в компонент card, чтобы перенаправить пользователя на страницу сведений, отображающую только выбранную статью? Я хотел бы включить фактическое содержимое, автора, дату и т.д. На этой странице только этой 1 статьи.
Спасибо

Комментарии:

1. Используете ли вы какой-либо маршрутизатор? Если это так, вы можете создать маршрут с параметром /science/:id . Затем в вашем компоненте card вы бы создали ссылку на маршрутизатор с указанием пути /science/${id} . На странице сведений вы должны использовать этот параметр URL, чтобы получить эту статью с этим идентификатором. Предполагая, что api способен с этим справиться.

2. Вы можете обернуть свое приложение в решение для маршрутизации / навигации и программно перейти к маршруту, который отображает детали конкретной статьи.