【问题标题】:Reactjs push route after dispatch调度后Reactjs推送路由
【发布时间】:2019-12-11 18:17:22
【问题描述】:

您好,在验证用户身份后,我无法找到可以通过推送调用路由的位置

我是用 redux 做的

我的行动:

const AuthenticateUser = (login, password) => {
    return dispatch => {
        dispatch (startAuth ());
        // fetching data
        api.post ('/ login', {login, password})
            .then (response => {
            localStorage.setItem ('token', response.data [0]);
            dispatch (userAuthenticated (response.data [1]))
        })
            .catch (err => {console.error (err);});
    }
}

export default AuthenticateUser;

我的减速机:

const authReducer = (state = initialState, action) => {
    switch (action.type) {
        case USER_AUTHENTICATED:
            return {
                ... state,
                loading: false,
                authenticated: true,
                user: action.user,
            }
        case USER_FAILED_AUTH:
            return {
                ... state,
                loading: false,
                message: action.error

            }
        default:
        return state;
    }
}

还有我的表格

const SignIn = (props) => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const [login, setLogin] = useState('');
  const [password, setPassword] = useState('');
  const handleSubmit = (e) => {
    e.preventDefault()
    dispatch(auth(login, password))
  }
  return (
    <div className={classes.root}>

      <Grid container spacing={2} className={classes.gridMain}>

        <Grid item lg={12} md={12} sm={12} xs={12} align="center">
          <img src={require("../nodejs-icon.svg")} alt="bug" height={100} />
        </Grid>

        <Grid item lg={12} md={12} sm={12} xs={12} className={classes.TextField}>
          <form onSubmit={handleSubmit}>
            <TextField
              className={classes.input2}
              id="demo2"
              label="Usuário"
              variant="outlined"
              value={login}
              onChange={(e) => setLogin(e.target.value)}
              InputLabelProps={{
                classes: {
                  root: classes.label,
                  focused: classes.focusedLabel,
                  error: classes.erroredLabel
                }
              }}
              InputProps={{
                classes: {
                  root: classes.cssOutlinedInput,
                  focused: classes.cssFocused,
                  notchedOutline: classes.notchedOutline,
                },
                startAdornment: (
                  <InputAdornment position="start">
                    <PersonSharpIcon style={{ fontSize: 25, color: 'rgba(20, 176, 12,0.9)' }} />
                  </InputAdornment>
                )
              }}
            />
            <TextField
              className={classes.txtFd}
              id="demo2"
              label="Senha"
              variant="outlined"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              InputLabelProps={{
                classes: {
                  root: classes.label,
                  focused: classes.focusedLabel,
                  error: classes.erroredLabel
                }
              }}
              InputProps={{
                classes: {
                  root: classes.cssOutlinedInput,
                  focused: classes.cssFocused,
                  notchedOutline: classes.notchedOutline,
                },
                startAdornment: (
                  <InputAdornment position="start">
                    <LockSharpIcon style={{ fontSize: 25, color: 'rgba(20, 176, 12,0.9)' }} />
                  </InputAdornment>
                )
              }}
            />
            <ButtonBase variant="raised" disableFocusRipple="false" disableRipple="false" centerRipple="false">
              <Typography noWrap className={classes.labelForgot} variant="subtitle2">
                Esqueci minha senha
          </Typography>
            </ButtonBase>
            <Button type="submit" className={classes.button} variant="raised" disableFocusRipple="false" disableRipple="false" centerRipple="false">
              Entrar
        </Button>
          </form>
        </Grid>

我有一个路由,在我验证此用户身份后,我想将其发送到路由或显示错误消息,但我不知道在代码中的何处执行此操作以及如何获取它。

我的路线

const AppRouter = () => (
  <BrowserRouter>
          <Route path="/xd" component={AuthPage} exact={true} /> 
          <Route path="/dashboard/addProduct" component={AddProduct} exact={true} /> 

  </BrowserRouter>
);

【问题讨论】:

  • 为什么不将push 函数作为参数传递给 AuthenticateUser 函数(这个函数可以使用 camelCase,因为它不是组件 authenticateUser)?如果请求成功并在那里调用它?我假设您正在使用 react 路由器,因此如果您正在使用它,您可以使用 withRouter 包装器将其放入您的组件中,然后将其传入。
  • 是的,我使用的是路由器浏览器,我用它编辑了答案,你能帮我怎么做吗?
  • 在您的SignIn 组件中,您需要导入此import { withRouter } from "react-router";,然后您包装您的组件,例如像这样export default withRouter(SignIn);,您将在SignIn 组件的道具中拥有history来自路由器并包含push 功能的道具,之后您可以在handleSubmit 中使用该道具,类似于dispatch(auth(login, password, push))
  • 并在我的函数上进行此登录: const SignIn = (props) => {
  • 我做了这个并且我的函数登录有推送未定义我给 console.log 道具并得到了这个:/历史:{长度:2,动作:“POP”,位置:{...}, createHref: ƒ, push: ƒ, ...} location: {pathname: "/xd", search: "", hash: "", state: undefined} match: {path: "/xd", url: "/xd" , isExact: true, params: {…}} staticContext: undefined

标签: reactjs redux


【解决方案1】:

所以这是为了给你一个可读的答案,而不是使用 cmets。 在您的SignIn 组件中:

import { withRouter } from "react-router-dom";
const SignIn = (props) => {
 const { history } = props;
 const { push } = history;
 // more variables
 const handleSubmit = (e) => {
  e.preventDefault()
  // You pass the push function over here.
  dispatch(auth(login, password, push))
 }
// Rest of the logic
}
export default withRouter(SignIn);

withRouter 将为您提供来自 react-router 的所有道具,这将允许您使用包含推送功能的历史对象将用户重定向到您想要的页面。

然后在您的身份验证功能中,我猜是“AuthenticateUser”功能,您可以这样做:

const AuthenticateUser = (login, password, push) => {
return dispatch => {
    dispatch (startAuth ());
    // fetching data
    api.post ('/ login', {login, password})
        .then (response => {
        localStorage.setItem ('token', response.data [0]);
        dispatch (userAuthenticated (response.data [1]))
        // push goes here
        push("/your-awesome-route")
    })
        .catch (err => {console.error (err);});
}
}

export default AuthenticateUser;

【讨论】:

  • 这对 vanilla redux 有效还是需要任何中间件?
  • 我相信问题中的用户正在使用 redux-thunk 不确定 tbh 但它应该可以在任何中间件上工作,或者没有它,我总是使用“redux-saga”来这样做
  • @Jean 你能再问我一个路线问题吗?
  • 确定是什么? @MykonSpt
  • 我的路由器浏览器中有一个结构,其中有我的
    我把所有内容路由
    但我需要两条路由没有显示我的导航栏页眉页脚,但我不能在这里我的 pastebin:pastebin.com/Eiu53dk7
【解决方案2】:

您可以在SignIn 组件中使用useEffect,该组件检查标志authenticated: true(此变量通过props 传递)并进行重定向。

类似的东西

  useEffect(() => {
    const { authenticated, navigation } = props;
    if (authenticated) {
        navigation.navigate(Routes.GoodPlace);
    }

  });

【讨论】:

  • 首先我需要使用 useSelector 选择状态?
  • mapStateToProps 应该将其传递给SignIn 组件。
猜你喜欢
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-14
  • 2020-11-30
  • 2019-06-01
  • 1970-01-01
  • 2022-01-18
相关资源
最近更新 更多