未捕获的类型错误:匹配未定义

Nee*_*ria 6 javascript frontend reactjs react-router

import books from '../books'


function BookScreen({ match }) {
    const book = books.find((b) => b._id === match.params.id)
    return (
        <div>
            {book}
        </div>
    )
}

export default BookScreen
Run Code Online (Sandbox Code Playgroud)

我不断收到错误匹配未定义。我看到了一个具有类似代码的教程,但在测试时似乎很好。任何线索可能是什么问题?

Dre*_*ese 13

如果matchprop 未定义,这可能是由于一些原因造成的。

react-router-domv5

如果使用 RRDv5,如果matchprop 未定义,则意味着BookScreen未接收在组件的prop 或prop函数上渲染组件时注入的路由 props。请注意,无论如何使用路由都会匹配和渲染,有关详细信息,请参阅路由渲染方法Routecomponentrenderchildrenchildren

确保实现以下其中一项来访问match对象:

  1. 在a 的 propBookScreen上渲染componentRoute

    <Route path="...." component={BookScreen} />
    
    Run Code Online (Sandbox Code Playgroud)
  2. BookScreen在a 的renderor childrenprop 函数上渲染Route并传递路由 props

    <Route path="...." render={props => <BookScreen {...props} />} />
    
    Run Code Online (Sandbox Code Playgroud)

    或者

    <Route path="...." children={props => <BookScreen {...props} />} />
    
    Run Code Online (Sandbox Code Playgroud)
  3. BookScreen使用高阶组件进行装饰withRouter以注入路由道具

    import { withRouter } from 'react-router-dom';
    
    function BookScreen = ({ match }) {
      const book = books.find((b) => b._id === match.params.id)
      return (
        <div>
          {book}
        </div>
      );
    };
    
    export default withRouter(BookScreen);
    
    Run Code Online (Sandbox Code Playgroud)
  4. 由于BookScreen是React函数组件,导入并使用钩子useParams来访问路由匹配参数

    import { useParams } from 'react-router-dom';
    
    ...
    
    function BookScreen() {
      const { id } = useParams();
      const book = books.find((b) => b._id === id)
      return (
        <div>
          {book}
        </div>
      );
    }
    
    Run Code Online (Sandbox Code Playgroud)

react-router-domv6

如果使用 RRDv6,则没有matchprop。路线道具不见了。这里只有useParams和 other 钩子存在,所以使用它们。

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

...

function BookScreen() {
  const { id } = useParams();
  const book = books.find((b) => b._id === id)
  return (
    <div>
      {book}
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

如果您有其他类组件并且正在使用 RRDv6 并且不想将它们转换为函数组件,那么您需要创建一个自定义withRouter组件。详细信息参阅我的回答。