是否可以在React Express自定义路由中使用'useEffect'钩子? [TYPO /已解决]

时间:2019-10-16 09:37:53

标签: node.js reactjs express react-hooks

我正在尝试创建一个受保护的路由处理程序,以检查是否允许我的用户访问页面, 到目前为止,我已经知道了:

import React from 'react';
import { Route } from 'react-router-dom';

import { AuthenticationContext } from '../../contexts/authentication/context';

import Unauthorized from '../Unauthorized';

import axios from 'axios';

const ProtectedRoute = ({ component: Component, redirect: Redirect, contextProvider: ContextProvider, path, ...routeProps }) => {

  const { authenticationState: {isAuthenticated, isLoading, currentUser} } = React.useContext(AuthenticationContext)

  console.log('called protected route handler', path)
  const [authorized, setAuthorized] = React.useState([]);
  const [isLoading2, setIsLoading2] = React.useState(true);

  React.useEffect(() => { // typo here (changed from useState() to useEffect())
    console.log('entered useState route')
    setIsLoading2(true);
    axios.get(`${global.REST_API_ADDR}/api/pages/${encodeURIComponent(path)}`)
    .then((response) => {

      setAuthorized(response.data.authorized);
      setIsLoading2(false);
    })
    .catch((error) => {
      setIsLoading2(false);
      console.log(error);
    })
  }, [path])

  return (
    <Route {...routeProps}
      render={ props => {
        if(isLoading || isLoading2) return <div>Chargement...</div>

        if(isAuthenticated && authorized.includes(currentUser.rank)){

          return ContextProvider ? <ContextProvider><Component {...props} /></ContextProvider> : <Component {...props} />
        }else if(isAuthenticated && !authorized.includes(currentUser.rank)) {
          return <Unauthorized {...props} />;
        }
        else{
          return <Redirect {...props}/>;
        }
    }}/>
  );

};

export default ProtectedRoute;

并在我的app.js中这样调用此ProtectedRoute组件:

import React, {Component} from 'react';
import {BrowserRouter as Router, Route, Switch, HashRouter} from 'react-router-dom';

// Components
import AdminFieldsManager from '../components/Admin/Fields/Manager';
import ApplicationBar from '../components/ApplicationBar';
import UserRegisterForm from '../components/User/Register/Form';
import UserLoginForm from '../components/User/Login/Form';
import Home from '../components/Home';
import Protected from '../components/Protected';
import Unauthorized from '../components/Unauthorized';
import Snackbar from '../components/Snackbar';
import Modal from '../components/Modal';
import TestSignature from '../components/TestSignature'
import ReworkManager from '../components/Rework/Manager';
import ReworkVizualizer from '../components/Rework/Visualizer';
import ReworkTreatmentManager from '../components/Rework/TreatmentManager';
import SocketHandler from '../components/socket/Handler/';
import KeyListenerHandler from '../components/keyListener/Handler';
import AdminChat from '../components/Admin/Chat';
import UserAuthenticationHandler from '../components/User/Authentication/Handler';
import UserTable from '../components/User/Table';
import AdminPagesManager from '../components/Admin/Pages/Manager';

// Contexts
import { AuthenticationContext, AuthenticationContextProvider, AuthenticationContextConsumer } from '../contexts/authentication/context';
import { AlterationFormContext, AlterationFormContextProvider, AlterationFormContextConsumer } from '../contexts/forms/AlterationFormContext';
import { ReworkManagerContext, ReworkManagerContextProvider, ReworkmanagerContextConsumer } from '../contexts/reworkManager/context';
import { ReworkVisualizerContext, ReworkVisualizerContextProvider, ReworkVisualizerContextConsumer} from '../contexts/reworkVisualizer/context';
import { FieldsManagerContext, FieldsManagerContextProvider, FieldsManagerContextConsumer} from '../contexts/admin/fieldsManager/context'
import { SnackbarContext, SnackbarContextProvider, SnackbarContextConsumer } from '../contexts/others/snackbar/context';
import { ConfirmationModalContext, ConfirmationModalContextProvider, ConfirmationModalConsumer } from '../contexts/others/confirmationModal/context';
import { SocketContext, SocketContextProvider, SocketContextConsumer } from "../contexts/socket/context";
import { ChatContext, ChatContextProvider, ChatContextConsumer} from "../contexts/admin/chat/context";

// Routes
import ProtectedRoute from '../components/routes/ProtectedRoute';
import GuestRoute from '../components/routes/GuestRoute';

// Material-UI
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import { MuiPickersUtilsProvider } from '@material-ui/pickers';

// Date-IO
import DateFnsUtils from '@date-io/date-fns';
import MomentUtils from '@date-io/moment';
import moment from 'moment';
import 'moment/locale/fr';
moment.locale("fr");

//theme
import CssBaseline from '@material-ui/core/CssBaseline';
import theme from './theme';
import './style.css';

// globals
global.REST_API_ADDR = 'http://localhost:5000';
//global.REST_API_ADDR = 'http://squale.epaas.eu.airbus.corp';

const App = () => {

  return (
    <MuiThemeProvider theme={theme}>
      <MuiPickersUtilsProvider utils={MomentUtils} locale="fr" libInstance={moment}>
        <CssBaseline/>
        <HashRouter>
          <React.Fragment>
            <SocketContextProvider>
              <SnackbarContextProvider>
                <ConfirmationModalContextProvider>
                  <AuthenticationContextProvider>
                    <UserAuthenticationHandler />
                    <SocketHandler />
                    <ChatContextProvider>
                      <KeyListenerHandler />
                      <AdminChat />
                    </ChatContextProvider>
                    <div style={{height:'100%', display:'flex', flexDirection:'column', flex:'1 1 auto', minWidth:0, minHeight:0}}>
                      <ApplicationBar />
                      <Switch>
                        <Route exact path='/' render={(props) => <Home />} />
                        <Route path="/unauthorized" render={(props) => <Unauthorized />} />
                        <GuestRoute path='/register' component={UserRegisterForm} redirect={Home} />
                        <GuestRoute path='/login' component={UserLoginForm} redirect={Home} />
                        <ProtectedRoute path="/users" component={UserTable} redirect={UserLoginForm} />
                        <ProtectedRoute path="/pagesconfig" component={AdminPagesManager} redirect={UserLoginForm} />
                        <ProtectedRoute path='/nonconformities' component={ReworkManager} redirect={UserLoginForm} contextProvider={ReworkManagerContextProvider} />
                        <ProtectedRoute path='/fieldsconfig' component={AdminFieldsManager} redirect={UserLoginForm} contextProvider={FieldsManagerContextProvider} />
                        <Route exact path='/testsignature' render={(props) => <TestSignature />} />
                        <ProtectedRoute path='/visualizer' component={ReworkVizualizer} redirect={UserLoginForm} contextProvider={ReworkVisualizerContextProvider} />
                        <ProtectedRoute path='/treatment' component={ReworkTreatmentManager} redirect={UserLoginForm} contextProvider={ReworkVisualizerContextProvider} />
                      </Switch>
                    </div>
                  </AuthenticationContextProvider>
                  <Modal />
                </ConfirmationModalContextProvider>
                <Snackbar />
              </SnackbarContextProvider>
            </SocketContextProvider>
          </React.Fragment>
        </HashRouter>
      </MuiPickersUtilsProvider>
    </MuiThemeProvider>
  );

}

export default App;

问题是useEffect挂钩仅在重新加载页面时触发一次,而在prop路径更改时则不会触发。每当用户更改页面时,如何使useEffect触发器?

预先感谢

编辑: 我做了一个错字,使用了useState而不是useEffect,谢谢Josed D.指出来!

0 个答案:

没有答案