应用程序将所有照片<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();
我再提两个可能会犯的错误,他们会面临同样的问题:
- 你可以用Router组件代替Route组件 你可能会忘记在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()看不到它