React Router / Redux / HOC 不适用于 'render' prop
React Router / Redux / HOC not working with 'render' prop
我正在使用 react router v4,我正试图解决与 react-router / redux / HOC 相关的问题。我有一个高阶组件在工作。 HOC 本身是 connect()
-ed 到 redux store。如果我通过 component
道具将其连接到 <Route />
中,这种方法非常有效:<Route path="/profile" component={ withAuth(Profile) } />
确实有效。
但是,当我尝试对 <Route />
和渲染道具执行相同操作时,它 不 起作用:<Route path="/profile" render={ () => withAuth(Profile) } />
控制台抛出“Route.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
" 当我省略 HOC 时它确实有效:<Route path="/profile" render={ () => <Profile /> } />
所以我怀疑 HOC 有问题但我找不到它。
我尝试使用 render
的原因是我想将额外的道具传递给 HOC。此外,我找不到错误,这让我很烦恼。
任何有新眼光的人都可以看看并让我走上正确的道路吗?谢谢!
/* === app.js === */
import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import Header from './header';
import Home from './home';
import Content from './about';
import Profile from './profile';
import withAuth from './withAuth';
import store from '../reducers/store';
export default class App extends Component {
render() {
return (
<Provider store={store}>
<div className="mdl-grid">
<Header />
<main className="mdl-layout__content">
<div className="page-content">
<Route path="/" exact component={Home} />
<Route path="/about" component={Content} />
<Route path="/profile" render={ () => withAuth(Profile) } />
</div>
</main>
</div>
</Provider>
)
}
}
/* === withAuth.js (Higher order component) === */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
const HOC = WrappedComponent => {
return class extends Component {
render() {
if (this.props.auth) {
return <WrappedComponent authenticated={this.props.auth} {...this.props} />
} else {
return <Redirect to="/" />
}
}
}
}
function mapStateToProps({ auth }) {
return { auth };
}
export default WrappedComponent => connect(mapStateToProps)( HOC(WrappedComponent) );
它不起作用的原因是,这里
<Route path="/profile" render={ () => withAuth(Profile) } />
render 实际上被分配了一个函数 withAuth 而不是返回值。你需要做的是
const AuthProfile = withAuth(Profile);
export default class App extends Component {
render() {
return (
<Provider store={store}>
<div className="mdl-grid">
<Header />
<main className="mdl-layout__content">
<div className="page-content">
<Route path="/" exact component={Home} />
<Route path="/about" component={Content} />
<Route path="/profile" render={ (props) => <AuthProfile {...props}/> } />
</div>
</main>
</div>
</Provider>
)
}
}
两者的区别
render={ () => withAuth(Profile) }
和
render={ (props) => <AuthProfile {...props}/> }
在第一种情况下,它是一个绑定到上下文的箭头函数。而在第二种情况下,它是一个返回组件的函数
我认为你的问题是你使用 <Redirect />
的方式,你必须把它放在 <Route />
中。看这个例子:
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
fakeAuth.isAuthenticated ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
)
我正在使用 react router v4,我正试图解决与 react-router / redux / HOC 相关的问题。我有一个高阶组件在工作。 HOC 本身是 connect()
-ed 到 redux store。如果我通过 component
道具将其连接到 <Route />
中,这种方法非常有效:<Route path="/profile" component={ withAuth(Profile) } />
确实有效。
但是,当我尝试对 <Route />
和渲染道具执行相同操作时,它 不 起作用:<Route path="/profile" render={ () => withAuth(Profile) } />
控制台抛出“Route.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
" 当我省略 HOC 时它确实有效:<Route path="/profile" render={ () => <Profile /> } />
所以我怀疑 HOC 有问题但我找不到它。
我尝试使用 render
的原因是我想将额外的道具传递给 HOC。此外,我找不到错误,这让我很烦恼。
任何有新眼光的人都可以看看并让我走上正确的道路吗?谢谢!
/* === app.js === */
import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import Header from './header';
import Home from './home';
import Content from './about';
import Profile from './profile';
import withAuth from './withAuth';
import store from '../reducers/store';
export default class App extends Component {
render() {
return (
<Provider store={store}>
<div className="mdl-grid">
<Header />
<main className="mdl-layout__content">
<div className="page-content">
<Route path="/" exact component={Home} />
<Route path="/about" component={Content} />
<Route path="/profile" render={ () => withAuth(Profile) } />
</div>
</main>
</div>
</Provider>
)
}
}
/* === withAuth.js (Higher order component) === */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
const HOC = WrappedComponent => {
return class extends Component {
render() {
if (this.props.auth) {
return <WrappedComponent authenticated={this.props.auth} {...this.props} />
} else {
return <Redirect to="/" />
}
}
}
}
function mapStateToProps({ auth }) {
return { auth };
}
export default WrappedComponent => connect(mapStateToProps)( HOC(WrappedComponent) );
它不起作用的原因是,这里
<Route path="/profile" render={ () => withAuth(Profile) } />
render 实际上被分配了一个函数 withAuth 而不是返回值。你需要做的是
const AuthProfile = withAuth(Profile);
export default class App extends Component {
render() {
return (
<Provider store={store}>
<div className="mdl-grid">
<Header />
<main className="mdl-layout__content">
<div className="page-content">
<Route path="/" exact component={Home} />
<Route path="/about" component={Content} />
<Route path="/profile" render={ (props) => <AuthProfile {...props}/> } />
</div>
</main>
</div>
</Provider>
)
}
}
两者的区别
render={ () => withAuth(Profile) }
和
render={ (props) => <AuthProfile {...props}/> }
在第一种情况下,它是一个绑定到上下文的箭头函数。而在第二种情况下,它是一个返回组件的函数
我认为你的问题是你使用 <Redirect />
的方式,你必须把它放在 <Route />
中。看这个例子:
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
fakeAuth.isAuthenticated ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
)