Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Axios请求不使用React+;重演_Node.js_Reactjs_Redux_React Redux - Fatal编程技术网

Node.js Axios请求不使用React+;重演

Node.js Axios请求不使用React+;重演,node.js,reactjs,redux,react-redux,Node.js,Reactjs,Redux,React Redux,我将尝试给出一个前提,然后用代码跟进它 我决定在我的React项目中实现MaterialUI,并且大部分工作都在进行中。如何设置应用程序,用户将面临登录页面。Login.js模块呈现,输入他们的凭据,然后单击submit。formData、onChange和onSubmit作为道具从登录组件传递给登录组件,登录组件通过MapStateTrops接收这些道具。登录组件使用connect中间件将redux状态链接到react应用程序 单击submit会触发formData(在传递给SignIn组件的

我将尝试给出一个前提,然后用代码跟进它

我决定在我的React项目中实现MaterialUI,并且大部分工作都在进行中。如何设置应用程序,用户将面临登录页面。Login.js模块呈现,输入他们的凭据,然后单击submit。
formData
onChange
onSubmit
作为道具从登录组件传递给登录组件,登录组件通过
MapStateTrops
接收这些道具。登录组件使用connect中间件将redux状态链接到react应用程序

单击submit会触发formData(在传递给SignIn组件的登录组件中)点击位于
“../../actions/auth”中的my
Login
方法。错误发生在这个方法中,在try-catch中的axios调用中,我试图与后端通信
const-response=wait-axios.post(“/api/auth”,body,config)

奇怪的是
dispatch({type:LOGIN\u SUCCESS,payload:response.data})
从不被命中,它应该将状态设置为从后端返回的令牌,因为似乎从未执行
LOGIN\u SUCCESS
。但是非常奇怪的是,控制台记录令牌实际上是有效的!似乎它从未被存储,而是强制调用AUTH_ERROR

这是我的登录组件:

 // Login.js
 import SignIn from "../../material/SignIn";

 const Login = ({ setAlert, login, isAuthenticated }) => {
 const [formData, setFormData] = useState({
 email: "",
 password: ""
 });

 const { email, password } = formData;

 const onChange = e => {
 setFormData({ ...formData, [e.target.name]: e.target.value });
 };

 const onSubmit = e => {
 login(email, password);
 };
 // Redirect if logged in
 if (isAuthenticated) {
 return <Redirect to="/dashboard" />;
 }

 return (
 <Fragment>
      <SignIn
      email={email}
      password={password}
      onSubmit={onSubmit}
      onChange={onChange}
      isAuthenticated={isAuthenticated}
      />
 </Fragment>
 );
 };

 Login.propTypes = {
 setAlert: PropTypes.func.isRequired,
 login: PropTypes.func.isRequired,
 isAuthenticated: PropTypes.bool
 };

 const mapStateToProps = state => ({
 isAuthenticated: state.auth.isAuthenticated
 });

 export default connect(
 mapStateToProps,
 { setAlert, login }
 )(Login);
 // Login user
 export const login = (email, password) => async dispatch => {
 // Config needed because we're sending data
 const config = {
 headers: {
      "Content-Type": "application/json"
 }
 };

 const body = JSON.stringify({ email, password });

 try {
 const response = await axios.post("/api/auth", body, config);

 // Skips over this dispatch
 dispatch({
      type: LOGIN_SUCCESS,
      payload: response.data
 });

 // But hits this dispatch.. and then console logs 'REACHED' as seen below
 dispatch(loadUser());
 } catch (err) {
 const errors = err.response.data.errors;

 if (errors) {
      errors.forEach(error => {
      dispatch(setAlert(error.msg, "danger"));
      });
 }

 dispatch({
      type: LOGIN_FAIL
 });
 }
 };
如果您注意到,在axios调用之后,
loadUser被调用
,定义为:

 // Load user
 export const loadUser = () => async dispatch => {
 const token = localStorage.token;

 console.log('REACHED!'); // reached

 if (token) {
 setAuthToken(token);
 }

 try {
 const response = await axios.get("/api/auth");

 dispatch({
      type: USER_LOADED,
      payload: response.data
 });
 } catch (err) {
 dispatch({
      type: AUTH_ERROR // This is dispatched
 });
 }
 };
后端路由如下所示:

 // @route  POST api/auth
 // @desc   Authenticate user and get token
 // @access Public
 router.post(
 "/",
 [
 check("email", "Please include a valid email").isEmail(),
 check("password", "Please is required").exists()
 ],
 async (req, res) => {
 const errors = validationResult(req);

 // send back any errors
 if (!errors.isEmpty()) {
      return res.status(400).json({
      errors: errors.array()
      });
 }

 const { email, password } = req.body;

 try {
      // check if user exists, send error if so
      let user = await User.findOne({ email });

      if (!user) {
      return res
           .status(400)
           .json({ errors: [{ msg: "Invalid credentials" }] });
      }

      const isMatch = await bcrypt.compare(password, user.password);

      if (!isMatch) {
      return res
           .status(400)
           .json({ errors: [{ msg: "Invalid credentials" }] });
      }
      // return jsonwebtoken so that way they're logged in right
      // away, without having to log in after registering
      const payload = {
      user: {
           id: user.id
      }
      };

      jwt.sign(
      payload,
      config.get("jwtSecret"),
      {
           expiresIn: process.env.PORT ? 3600 : 36000
      },
      (err, token) => {
           if (err) throw err;

           console.log(token); // prints token!

           return res.json({ token });
      }
      );
 } catch (err) {
      console.log(err);
      res.status(500).send("Server error");
 }
 }
 );

在这一点上我很困惑。正在呈现令牌,但React似乎没有在节点有机会将其发送回之前“等待”响应。

不知道如何解释这一点,但我通过从表单标记中去掉onSubmit触发器并将其放置在in SignIn.js上解决了这一问题。我将按钮的类型也更改为类型按钮。让它工作:)

不知道如何解释,但我解决了这个问题,从表单标签中去掉了onSubmit触发器,并将其放在in-SignIn.js中。我将按钮的类型也更改为类型按钮。让它工作起来:)

您使用的是什么中间件?它需要支持异步操作。您说过“错误发生…”,但不清楚错误发生的位置和原因。这是AJAX请求中的错误吗?还是JS例外?“记录代币实际有效”您在哪里尝试记录代币?@EricHasselbring在我决定尝试实现Material UI之前,一切都很好。@ThiagoBarcala在我在问题中发布的最后一个函数中,在JWT.sign的
POST api/auth
中。似乎令牌是在后端创建的,但在前端的
const response=wait..
中没有返回您使用的中间件是什么?它需要支持异步操作。您说过“错误发生…”,但不清楚错误发生的位置和原因。这是AJAX请求中的错误吗?还是JS例外?“记录代币实际有效”您在哪里尝试记录代币?@EricHasselbring在我决定尝试实现Material UI之前,一切都很好。@ThiagoBarcala在我在问题中发布的最后一个函数中,在JWT.sign的
POST api/auth
中。似乎令牌是在后端创建的,但不会在前端的
const response=wait..
中返回
 // @route  POST api/auth
 // @desc   Authenticate user and get token
 // @access Public
 router.post(
 "/",
 [
 check("email", "Please include a valid email").isEmail(),
 check("password", "Please is required").exists()
 ],
 async (req, res) => {
 const errors = validationResult(req);

 // send back any errors
 if (!errors.isEmpty()) {
      return res.status(400).json({
      errors: errors.array()
      });
 }

 const { email, password } = req.body;

 try {
      // check if user exists, send error if so
      let user = await User.findOne({ email });

      if (!user) {
      return res
           .status(400)
           .json({ errors: [{ msg: "Invalid credentials" }] });
      }

      const isMatch = await bcrypt.compare(password, user.password);

      if (!isMatch) {
      return res
           .status(400)
           .json({ errors: [{ msg: "Invalid credentials" }] });
      }
      // return jsonwebtoken so that way they're logged in right
      // away, without having to log in after registering
      const payload = {
      user: {
           id: user.id
      }
      };

      jwt.sign(
      payload,
      config.get("jwtSecret"),
      {
           expiresIn: process.env.PORT ? 3600 : 36000
      },
      (err, token) => {
           if (err) throw err;

           console.log(token); // prints token!

           return res.json({ token });
      }
      );
 } catch (err) {
      console.log(err);
      res.status(500).send("Server error");
 }
 }
 );