高阶函数渲染两次导致子组件被触发
higher order function render twice causing child component to be triggered
我有一个受保护的路由,使用高阶组件实现,但是在我的App.js子组件中,触发它的componentDidMount方法,我想知道为什么会这样..
Route.js
...
<BrowserRouter>
<Switch>
<Route exact path='/app' component={CheckPermission(App)} />
<Route exact path='/app/login' component={Login} />
</Switch>
</BrowserRouter>
...
Auth.js
export default function CheckPermission(EnhancedComponent) {
class Auth extends Component {
static contextTypes = {
router: PropTypes.object
}
componentWillMount() {
if (!this.props.isAuth) {
this.context.router.history.replace(`/login`)
}
}
componentWillUpdate() {
if (!this.props.isAuth) {
this.context.router.history.replace(`/login`)
}
}
render() {
return <EnhancedComponent { ...this.props } />
}
}
return connect()(Auth)
}
App.js
class App extends Component {
componentDidMount(){
console.log('test') //why is this trigger??
}
render() {
return <h1>App</h1>
}
}
如果我在 App.js 的 componentDidMount 中有 API 调用,它会导致不需要的调用,我认为 Auth.js 的 componentWillMount 已经阻止渲染触发了?我在浏览器中看到,Auth.js 的重定向刚刚起作用。
无法保证 componentWillMount
中的 replace 方法会在 render 方法触发之前重定向。
您可能希望将 Auth.js
代码重构为类似这样的代码。
export default function CheckPermission(EnhancedComponent) {
class Auth extends Component {
render() {
// Note that we return a <Redirect /> component here early for not giving <EnhancedComponent /> any chance to render itself.
if (!this.props.isAuth) {
return <Redirect to="/login" />
}
return <EnhancedComponent { ...this.props } />
}
}
return connect()(Auth)
}
我有一个受保护的路由,使用高阶组件实现,但是在我的App.js子组件中,触发它的componentDidMount方法,我想知道为什么会这样..
Route.js
...
<BrowserRouter>
<Switch>
<Route exact path='/app' component={CheckPermission(App)} />
<Route exact path='/app/login' component={Login} />
</Switch>
</BrowserRouter>
...
Auth.js
export default function CheckPermission(EnhancedComponent) {
class Auth extends Component {
static contextTypes = {
router: PropTypes.object
}
componentWillMount() {
if (!this.props.isAuth) {
this.context.router.history.replace(`/login`)
}
}
componentWillUpdate() {
if (!this.props.isAuth) {
this.context.router.history.replace(`/login`)
}
}
render() {
return <EnhancedComponent { ...this.props } />
}
}
return connect()(Auth)
}
App.js
class App extends Component {
componentDidMount(){
console.log('test') //why is this trigger??
}
render() {
return <h1>App</h1>
}
}
如果我在 App.js 的 componentDidMount 中有 API 调用,它会导致不需要的调用,我认为 Auth.js 的 componentWillMount 已经阻止渲染触发了?我在浏览器中看到,Auth.js 的重定向刚刚起作用。
无法保证 componentWillMount
中的 replace 方法会在 render 方法触发之前重定向。
您可能希望将 Auth.js
代码重构为类似这样的代码。
export default function CheckPermission(EnhancedComponent) {
class Auth extends Component {
render() {
// Note that we return a <Redirect /> component here early for not giving <EnhancedComponent /> any chance to render itself.
if (!this.props.isAuth) {
return <Redirect to="/login" />
}
return <EnhancedComponent { ...this.props } />
}
}
return connect()(Auth)
}