Because my outlet is placed in the accordion body of react-bootstrap, So when I enter the sub-route, the useEffect content of the sub-route is always executed. until the body of the accordion is fully opened,Wondering if there is a way to fix it.
The problem is that the outlet can't seem to be placed in accordion.body, I hope there is a solution, thank you! ! !
This is the parent route:
import React from 'react'
import { useParams, Link, Outlet } from 'react-router-dom'
import request from '../common/utils'
import { Spinner, Accordion } from 'react-bootstrap'
export default function ReposList() {
let user = useParams()
let [userData, setUserData] = React.useState(null)
let [isLoading, setLoading] = React.useState(true)
let [isPage, setPage] = React.useState(2)
function getAPI(per_page, page) {
return request({
url: `users/${user.username}/repos`,
params: {
per_page,
page
}
})
}
//下拉加載
function handleScroll(e) {
if (e.target.clientHeight + parseInt(e.target.scrollTop)
=== e.target.scrollHeight) {
getAPI(10, isPage).then((res) => {
setUserData([...userData, ...res.data])
})
setPage(isPage + 1)
}
}
React.useEffect(() => {
const fetchData = async () => {
const result = await getAPI(10, 1)
setUserData(result.data)
//console.log(res.data)
setLoading(false)
console.log(1)
}
fetchData()
}, [])
if (isLoading) {
return (
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
)
}
//手風琴要包著map生成的item,不然item之間沒有對摺效果
return (
<div className='repos' onScroll={handleScroll} >
<Accordion>
{userData.map((data) => (
// key要放在元素的最上方,不然會報錯。
<Accordion.Item eventKey={data.id} key={data.id}>
<Accordion.Header as={Link} to={data.name}>
{data.name}{ ' '}{data.language == null? '': `/ ${data.language}`}
</Accordion.Header>
<Accordion.Body>
<Outlet/>
</Accordion.Body>
</Accordion.Item>
))}
</Accordion>
</div>
)
}
This is the sub route:
import React from 'react'
import { useParams } from 'react-router-dom'
import { Spinner , Table } from 'react-bootstrap'
import request from '../common/utils'
export default function Repo() {
let user = useParams()
let [userData, setUserData] = React.useState(null)
let [isLoading , setLoading] = React.useState(true)
//console.log(user)
function getAPI(per_page,page) {
return request({
url: `repos/${user.username}/${user.repo}`,
params:{
per_page,
page
}
})
}
React.useEffect(() => {
const fetchData = async () => {
const result = await getAPI()
setUserData(result.data)
//console.log(res.data)
setLoading(false)
console.log(1)
}
fetchData()
}, [user])
if (isLoading) {
return (
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
)
}
return(
<Table striped bordered hover size="sm"
className='repoTable'>
<thead>
<tr>
<th>full_name</th>
<th>description</th>
<th>stargazers_count</th>
<th>url</th>
</tr>
</thead>
<tbody>
<tr>
<td>{userData.full_name}</td>
<td>{userData.description == null? 'null' : userData.description}</td>
<td>{userData.stargazers_count}</td>
<td>
<a href={userData.svn_url }target="_blank">
Go!
</a>
</td>
</tr>
</tbody>
</Table>
)
}
Complete code and demo https://github.com/superrjohn/GithubRestApi
Hope someone can help, thanks!