1

我有这堂课:

export default class Panel extends PureComponent {
    constructor(props){
        super(props);
        this.state = {
            loading: true,
            url: '/' +this.props.lang+ '/panel',
            about: '/' +this.props.lang+ '/panel' + '/about',
            user: '/' +this.props.lang+ '/panel' + '/user/1',
            userPath: '/' +this.props.lang+ '/panel' + '/user/:id'
        }


    }
    componentDidMount(){
        this.setState({
            loading: false
        });
        console.log(this.state.user);
    }

    onResize(width){
        var totalWidth  = width + 250 + "px";
        var contentWidth  = width + "px";
        document.querySelector('.panel__slideContainer').style.width = totalWidth;
        document.querySelector('.mainContainer').style.width = contentWidth;

    }
    render() {
        if(this.state.loading === true){
            return <p>Loading...</p>
        }
        return (

            <div className="container panel__container">
            <Router>

                <ReactResizeDetector handleWidth onResize={this.onResize} />
                <div className="panel__slideContainer">

                <nav className="panel__sideMenu">

                    <ul>
                        <li>
                             <NavLink exact activeClassName="active" to={this.state.url}>Home</NavLink>
                        </li>
                        <li>
                            <NavLink activeClassName="active" to={this.state.about}><Trans>change password</Trans></NavLink>

                        </li>
                        <li>
                            <NavLink  activeClassName="active" to="/pl/panel/user/1">User</NavLink>
                        </li>
                    </ul>
                </nav>
                <div className="mainContainer">
                    <Nav />
                <div>
                    <Switch>
                        <Route exact path={this.state.url}>
                            <Home />
                        </Route>
                        <Route path={this.state.about} >
                            <About />
                        </Route>
                        <Route path="/pl/panel/user/:id">
                            <User />
                        </Route>
                    </Switch>
                </div>
        </div>
            </div>
            </Router>
            </div>
          );
    }
}

我对未读取道具的用户组件有疑问。在我尝试显示路线之前没有<Switch>这样的:

<Route path="" component={} />

并且在单击组件正确加载并显示道具后,但在刷新网站后它显示错误 404。实施 Switch 后,它绝对坏了。没有显示(只有控制台日志错误)

// This is the error:
> Cannot read property 'params' of undefined
> backend.js:6 The above error occurred in the <User> component:
> Uncaught TypeError: Cannot read property 'params' of undefined

@Edit 用户组件从 'react' 导入 React;

const User = (props) => {
  return (
    <div>
<p>User id: {props.match.params.id}</p>
    </div>
  );
}

export default User;

知道如何解决我的问题吗?

4

1 回答 1

0

match此错误是由于组件中未定义道具引起的<User/>,当"/pl/panel/user/:id"路由匹配时,这反过来意味着在params.id访问时抛出异常。

有一些解决方案可以解决这个问题 - 一个简单的解决方法是通过prop指定User组件:<Route/>component

<Route path="/pl/panel/user/:id" component={User} />

通过这种方式指定User组件,react-router 会在路由匹配并渲染组件时自动将matchprop 注入。User

另一种选择是使用withRouter

import { withRouter } from "react-router-dom";

/* Your current User component left as is */
const User = (props) => { ... }

/* Router injected into User */
const UserWithRouter = withRouter(User);

<Route path="/pl/panel/user/:id">
    {/* Use UserWithRouter instead, match will now be defined in User */}
    <UserWithRouter />
</Route>

HOC 与第一种方法的withRouter效果相同,导致在渲染组件时将matchprop 注入到目标组件(即User)中。UserWithRouter

更新

您在刷新浏览器时看到的 404 错误可能是由于客户端和服务器端路由不一致。

例如,导航到/pl/panel/user/1客户端上的路由然后刷新页面将向您的服务器发出请求以获取/pl/panel/user/1. 因为服务器不知道如何处理,通常会返回 404。

一个简单的解决方法是在您的客户端代码中<BrowserRouter>替换为。<HashRouter>这将为您的 url 路径添加前缀#,但是它将允许您需要的重新加载行为,而无需对后端进行任何更改。

希望有帮助!

于 2020-01-07T19:27:21.817 回答