使用 redux 进行打开状态时 Material-ui 对话框闪烁

ist*_*ert 5 javascript reactjs redux material-ui

我正在尝试将 Material-ui 对话框的打开状态移至 redux,以防止其在重新渲染发生时关闭,但在发生重新渲染时我遇到了对话框问题。虽然状态保存在 redux 中,并且每当重新渲染发生时对话框都会保持打开状态,但打开状态保持打开状态,但对话框确实显示打开动画(淡入),这有点烦人。

Students.js(模式的父组件)

const Students = ({
    app: { studentsPage: { savedAddDialogOpen }},
  setStudentsPageAddDialogOpen}) => {

    // Create the local states
    const [dialogOpen, setDialogOpen] = React.useState(savedAddDialogOpen);
    const dialogOpenRef = React.useRef(savedAddDialogOpen);

    // Change redux dialog open
    const setReduxDialogState = () => {
      setStudentsPageAddDialogOpen(dialogOpenRef.current, savedAddDialogOpen);
    };

    // Open add student dialog
    const dialogClickOpen = () => {
      setDialogOpen(true);
      dialogOpenRef.current = true;
      setTimeout(() => setReduxDialogState(), 300);
    };

    // Close add student dialog
    const dialogClose = () => {
      setDialogOpen(false);
      dialogOpenRef.current = false;
      setTimeout(() => setReduxDialogState(), 300);
    };

    return (
      <Container>
        {/* Add student modal */}
        <AddStudentModal dialogOpen={dialogOpen} dialogClose={dialogClose} />
      </Container>
    )

}

// Set the state for this component to the global state
const mapStateToProps = (state) => ({
  app: state.app,
});
Run Code Online (Sandbox Code Playgroud)

AddStudentModal.js

const AddStudentModal = ({
    dialogOpen, dialogClose
    }) => {

    return (
      <Dialog
        open={dialogOpen}
      >
        {/* Lots of stuff*/}
        <DialogActions>
          <Button onClick={dialogClose}>
            Close dialog
          </Button>
        </DialogActions>
      </Dialog>
    )
};

Run Code Online (Sandbox Code Playgroud)

我希望这应该足够了。我尝试检查重新渲染发生时打开状态是否实际上正确,并且每次都是正确的,但看起来对话框在重新渲染时关闭,无论打开状态是什么,并且仅几毫秒后实际上注意到它应该是打开。

任何帮助将非常感激

编辑1:发现它与来自redux的打开状态无关,如果我使用open={true}它仍然闪烁,所以可能是material-ui本身的问题?

编辑2:PrivateRoute.js

const PrivateRoute = ({
  auth: { isAuthenticated, loadingAuth },
  user: { loggedInUser },
  component: Component,
  roles,
  path,
  setLastPrivatePath,
  ...rest
}) => {
  useEffect(() => {
    if (path !== '/dashboard' && path !== '/profile') {
      setLastPrivatePath(path);
    }
    // Prevent any useless errors with net line:
    // eslint-disable-next-line
  }, [path]);

  // If we are loading the user show the preloader
  if (loadingAuth) {
    return <Preloader />;
  }

  // Return the component (depending on authentication)
  return (
    <Route
      {...rest}
      render={props =>
        !isAuthenticated ? (
          <Redirect to="/login" />
        ) : (loggedInUser && roles.some(r => loggedInUser.roles.includes(r))) ||
          roles.includes('any') ? (
          <Component {...props} />
        ) : (
          <NotAuthorized />
        )
      }
    />
  );
};

// Set the state for this component to the global state
const mapStateToProps = state => ({
  auth: state.auth,
  user: state.user
});

Run Code Online (Sandbox Code Playgroud)

ist*_*ert 2

感谢@RyanCogswell,我发现了这个问题!

对于任何遇到同样问题的人来说,这就是我的原因和解决方法:

我将组件传递到 Route 组件中,如下所示:

<PrivateRoute
   exact
   path={'/dashboard/students'}
   component={(props) => (
     <Students {...props} selectedIndex={selectedIndexSecondary} />
   )}
   roles={['admin']}
/>
Run Code Online (Sandbox Code Playgroud)

通过这样做,我可以通过我的 privateRoute 函数传递 props,但是如果您在普通 Route 组件中以这种方式发送组件,也会发生这种情况

对我来说,解决方案只是将 selectedIndexSecondary 移动到 redux 并以阻止重新安装的正常方式发送组件。

所以只要这样做就可以防止这种情况发生。

<PrivateRoute
   exact
   path={'/dashboard/students'}
   component={Students}
   roles={['admin']}
/>
Run Code Online (Sandbox Code Playgroud)

此外,这还将解决组件中的本地状态重置为默认值的问题。所以对我来说它解决了两个问题!