有一個頁面上有很多故事,當您單擊任何故事時,應該會打開一個包含該故事的新頁面。但是當我打開一個新頁面時,我沒有得到這個故事的“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>
uj5u.com熱心網友回復:
問題
根據我對代碼的理解,該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
prop 并通過 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;
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/533612.html
標籤:反应反应挂钩反应路由器