【问题标题】:How to redirect from page to page by id?如何通过 id 从一个页面重定向到另一个页面?
【发布时间】:2022-11-15 08:09:48
【问题描述】:

有一个页面上有很多故事,当您单击任何故事时,应该会打开一个包含该故事的新页面。但是当我打开一个新页面时,我没有得到这个故事的“id”.json,而是得到 undefined.json。请帮帮我

带主页的代码 `

import React, { useEffect, useState } from 'react';
import { Story } from '../components/Story';
import { getStoryIds } from '../services/hnApi';
import { useInfiniteScroll } from '../hooks/useInfiniteScroll';

export const Home = () => {
  const {count} = useInfiniteScroll(); 
  const [storyIds, setStoryIds] = useState([]);

  useEffect(() => {
    getStoryIds().then(data => setStoryIds(data));
  }, []);

  return storyIds.slice(0, count).map(storyId => (
    <Story key={storyId} storyId={storyId} />
  ));
};

export default Home;

`

有故事的代码

`

/* eslint-disable react-hooks/exhaustive-deps */
import React, { useState, useEffect} from 'react';
import { getStory } from '../services/hnApi';
import { Card, Container, Nav } from 'react-bootstrap'
import { mapTime } from '../mappers/mapTime';
import { Link } from 'react-router-dom';

export const Story = ({storyId}) => {
    const[story, setStory] = useState({});
    const {id} = story;

    useEffect(() => {
        const timer = setTimeout(() => {
          window.location.reload();
        }, 60000);
        return () => clearTimeout(timer);
      }, []);

    useEffect(() => {
        getStory(storyId).then((data) => data.url && setStory(data))
    }, []);

    return story && story.url ? (   
        <Container data-id={id} fluid="xl" style={{marginTop: "1%", marginBottom: "1%"}}>
            <Nav.Item>
                <Link to={`/storyPage/${id}`} state={{ id: 'id' }}
                style={{ textDecoration: 'none' }}>
                    <Card style={{ paddingLeft: "1%", paddingTop: "1%", paddingBottom: "1%"}}>
                        <Card.Title>{story.title}</Card.Title>
                        <br/>
                        <Card.Text style={{color: 'black', fontStyle: 'italic', fontSize: '15px'}}>Author: {story.by}</Card.Text>
                        <Card.Text style={{color: 'black', fontStyle: 'italic', fontSize: '15px'}}>Posted: {mapTime(story.time)}</Card.Text>
                        <Card.Text style={{color: 'black', fontStyle: 'italic', fontSize: '15px'}}>Rating: {story.score}</Card.Text>
                    </Card>
                </Link>
            </Nav.Item>
        </Container>
    ):null;
};
export default Story;

`

应该打开我需要的故事的代码

`

import React, { useEffect, useState } from 'react';
import { getStoryIds } from '../services/hnApi';
import { Button, Container } from 'react-bootstrap';
import { ArrowLeft } from 'react-bootstrap-icons';
import { StorySingular } from './StorySingular';

export const StoryPage = ( ) => {
  const [storyId, setStoryId] = useState([]);
  const {id} = storyId;

  useEffect(() => {
    getStoryIds().then(data => setStoryId(data));
  }, []);

  return storyId.slice(0, 1).map(storyId => (
    <Container key={storyId}>
      <Button style={{marginLeft: '1%', marginTop:'1%'}} variant="outline-info" href='/'><ArrowLeft/></Button>
      <br/>
      <StorySingular storyId={id} />
    </Container>
  ));
};

export default StoryPage;

`

`

/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useState } from 'react';
import { getStory } from '../services/hnApi';
import { Card, Container, Nav } from 'react-bootstrap';
import { Comments } from '../comments/Comments';
import { mapTime } from '../mappers/mapTime';

export const StorySingular = ({ storyId }) => {
  const [story, setStory] = useState({});
  const { kids, id, url } = story;
    
  useEffect(() => {
    getStory(storyId).then((data) => {
      if (data && data.url) {
        setStory(data);
      }
    });
  }, []);

  return story && url ? (
    <>
      <Container data-id={id}>
        <Card style={{paddingLeft: "1%", paddingTop: "1%"}}>
            <Card.Title style={{paddingLeft: "1%"}}>{story.title}</Card.Title>
            <Nav.Link href={story.url}>{url}</Nav.Link>
            <br/>
            <Card.Text style={{color: 'black', fontStyle: 'italic',paddingLeft: "1%", fontSize: '14px'}}>Author: {story.by}</Card.Text>
            <Card.Text style={{color: 'black', fontStyle: 'italic',paddingLeft: "1%", fontSize: '14px'}}>Posted: {mapTime(story.time)}</Card.Text>
            <Card.Text style={{color: 'black', fontStyle: 'italic',paddingLeft: "1%", fontSize: '14px'}}>Comments: {story.descendants}</Card.Text>
            <Card.Text>{kids && <Comments commentIds={kids} root />}</Card.Text>
        </Card>
    </Container>
    </> 
  ): null;
};

export default StorySingular;

`

             <Router>
                <Switch>
                    <Route exact path="/storyPage/:id" component={StoryPage} />
                </Switch>
            </Router>

【问题讨论】:

  • 您是否尝试从 StoryPage 组件中的 "/storyPage/:id" 访问 id 路由路径参数?
  • 你能在 StoryPage 中获取 storyId 吗?
  • @CircuitPlanet 在 StoryPage 中,我总是得到第一个故事的 ID
  • @DrewReese 我正在尝试获取故事的 ID,以便所选故事出现在 StoryPage 上 :)

标签: reactjs react-hooks react-router


【解决方案1】:

问题

根据我对代码的理解,Home 组件获取故事 ID 并将它们映射到 Story 组件的数组。

export const Home = () => {
  const {count} = useInfiniteScroll(); 
  const [storyIds, setStoryIds] = useState([]);

  useEffect(() => {
    getStoryIds().then(data => setStoryIds(data));
  }, []);

  return storyIds.slice(0, count).map(storyId => (
    <Story key={storyId} storyId={storyId} />
  ));
};

Story 组件然后获取传递的 storyId 属性并通过 id 获取指定的故事并将其呈现为卡片组件中的链接和一些基本细节。

export const Story = ({ storyId }) => {
  const[story, setStory] = useState({});
  const {id} = story;

  useEffect(() => {
    const timer = setTimeout(() => {
      window.location.reload();
    }, 60000);
    return () => clearTimeout(timer);
  }, []);

  useEffect(() => {
    getStory(storyId).then((data) => data.url && setStory(data))
  }, []);

  return story && story.url ? (   
    <Container data-id={id} fluid="xl" style={{ marginTop: "1%", marginBottom: "1%" }}>
      <Nav.Item>
        <Link
          to={`/storyPage/${id}`}
          state={{ id: 'id' }}
          style={{ textDecoration: 'none' }}
        >
          ....
        </Link>
      </Nav.Item>
    </Container>
  ) : null;
};

export default Story;

StoryPage 组件呈现在链接到的路径上:

<Route exact path="/storyPage/:id" component={StoryPage} />

从这里看起来逻辑有点偏离。 StoryPage 组件再次请求所有故事 ID,而不是获取特定故事。这应该与 Home 组件获取的 id 数组相同。

export const StoryPage = () => {
  const [storyId, setStoryId] = useState([]);
  const { id } = storyId;

  useEffect(() => {
    getStoryIds().then(data => setStoryId(data)); // <-- fetches ids again
  }, []);

  return storyId.slice(0, 1).map(storyId => (
    <Container key={storyId}>
      <Button
        style={{ marginLeft: '1%', marginTop: '1%' }}
        variant="outline-info"
        href='/'
      >
        <ArrowLeft />
      </Button>
      <br/>
      <StorySingular storyId={id} />
    </Container>
  ));
};

然后 StorySingular 组件似乎通过 id 获取特定的故事。

export const StorySingular = ({ storyId }) => {
  const [story, setStory] = useState({});
  const { kids, id, url } = story;
    
  useEffect(() => {
    getStory(storyId).then((data) => {
      if (data && data.url) {
        setStory(data);
      }
    });
  }, []);

  return story && url ? (
    <>
      ....
    </> 
  ) : null;
};

解决方案

我相信您的用户界面可以稍微简化一下。 Home 组件获取故事 ID 并使用指向特定故事的链接呈现它们。

<Router>
  <Switch>
    <Route path="/storyPage/:id" component={StoryPage} />
    <Route path="/" component={Home} />
  </Switch>
</Router>

StoryPage 更新为从路由路径参数中读取故事 id 值并获取要呈现的特定故事。

import { useParams } from 'react-router-dom';

export const StoryPage = () => {
  const { id } = useParams();

  const [story, setStory] = useState();

  useEffect(() => {
    getStory(id)
      .then((data) => {
        if (data && data.url) {
          setStory(data);
        }
      });
  }, [id]); // <-- fetch story when id changes

  return (
    <Container>
      <Button
        style={{ marginLeft: '1%', marginTop: '1%'}}
        variant="outline-info"
        href='/'
      >
        <ArrowLeft />
      </Button>
      <br/>
      {story && <StorySingular story={story} />}
    </Container>
  );
};

...

export const StorySingular = ({ story }) => {
  const { kids, id, url } = story;

  return story && url ? (
    <Container data-id={id}>
      <Card .... >
        <Card.Title .... >
          {story.title}
        </Card.Title>
        <Nav.Link href={story.url}>{url}</Nav.Link>
        <br/>
        <Card.Text .... >
          Author: {story.by}
        </Card.Text>
        <Card.Text .... >
          Posted: {mapTime(story.time)}
        </Card.Text>
        <Card.Text .... >
          Comments: {story.descendants}
        </Card.Text>
        <Card.Text>
          {kids && <Comments commentIds={kids} root />}
        </Card.Text>
      </Card>
    </Container>
  ): null;
};

【讨论】:

  • 非常感谢你,我的朋友!你刚刚救了我 :) 祝你好运,再次感谢
【解决方案2】:

不确定,添加storyId依赖并检查。

useEffect(() => {
  getStory(storyId).then((data) => data.url && setStory(data));
}, [storyId]);

【讨论】:

  • 不工作 :(
猜你喜欢
  • 1970-01-01
  • 2011-08-22
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 2015-08-14
相关资源
最近更新 更多