useParams钩子在react功能组件中返回undefined



应用程序将所有照片<Photo>显示在一个网格<PhotoGrid>中,然后一旦点击,<Photo>中的一个功能将URL更改为history.push,路由器使用useParams钩子根据URL呈现<Single>

PhotoGrid->Photo(更改URL onClick) ->Single基于URL (useParams)。我一定是搞砸了什么,因为useParams返回undefined。

感谢所有先进的想法。App.js

class App extends Component {
render() {
return (
<>
<Switch>
<Route exact path="/" component={PhotoGrid}/>
<Route path="/view/:postId" component={Single}/>
</Switch>
</>
)
}
}
export default App;

Photogrid.js

export default function PhotoGrid() {
const posts = useSelector(selectPosts);
return (
<div>
hi
{/* {console.log(posts)} */}
{posts.map((post, i) => <Photo key={i} i={i} post={post} />)}
</div>
)
}

在Photo I更改URL与history.push

const selectPost = () => {
(...)
history.push(`/view/${post.code}`);
};

Single.js

import { useParams } from "react-router-dom";
export default function Single() {
let { id } = useParams();
console.log("id:",  id)   //returns undefined
return (
<div className="single-photo">
the id is: {id} //renders nothing
</div>
)
}

当使用useParams时,您必须将解构结构let { postId } = useParams();匹配到您的路径"/view/:postId"

工作Single.js

import { useParams } from "react-router-dom";
export default function Single() {
const { postId } = useParams();
console.log("this.context:",  postId )
return (
<div className="single-photo">
{/* render something based on postId */}
</div>
)
}

您应该使用与Route path中提到的相同的解构结构。在本例中,您应该这样写:

let { postID } = useParams();

我再提两个可能会犯的错误,他们会面临同样的问题:

  1. 你可以用Router组件代替Route组件
  2. 你可能会忘记在Route组件的path属性中提到这个参数,而你应该在Link to组件中提到它。

确保调用useParams()的组件确实是<Route>的子组件

小心ReactDOM.createPortal

const App = () => {
return (
<>
<Switch>
<Route exact path="/" component={PhotoGrid}/>
<Route path="/view/:postId" component={Single}/>
</Switch>
<ComponentCreateWithPortal /> // Impossible to call it there
</>
)
}

您必须检查您正在使用的API。有时它不仅仅被称为id。这就是为什么useParams()看不到它

最新更新