【问题标题】:How to get imported functions to set state of functional component?如何获取导入的函数来设置功能组件的状态?
【发布时间】:2021-01-06 08:45:15
【问题描述】:

我有一个带有相当长的 onSubmit 函数的 react 类组件,我已将其放入另一个文件中,以使代码更整洁。

我尝试将类组件转换为功能组件,用 useState 替换我的所有 state 和 setState 函数,但现在我的 useState 状态更新程序在导入的函数中返回 undefined。我可以使用带有功能组件的导入函数来更新状态吗?该函数在导入到类组件时运行良好,并且我的状态更新器是 setState();

//Imported function in utils.js

export const loginUser = async function (email, password) {
    try {
        const login = await axios.post('http://localhost:5000/api/v1/auth/login', {
            email,
            password
        });
        const options = {
            headers: {
                Authorization: `Bearer ${login.data.token}`
            }
        };
        const getUser = await axios.get(
            'http://localhost:5000/api/v1/auth/me',
            options
        );
        const user = getUser.data.data;
        setAuthenticated(true);
        setUser(getUser.data.data);
        setEmail('');
        setPassword('');

        localStorage.setItem('user', JSON.stringify(user));
        console.log(localStorage.getItem('user'));
    } catch (err) {
        console.log(err);
    }
};

// Functional component with imported function

import React, { useState } from 'react';
import axios from 'axios';
import PropTypes from 'prop-types';
import { Login } from './Login';


const { loginUser } = require('../utils/utils');

export const Splash = () => {
    const [user, setUser] = useState(null);
    const [error, setError] = useState(null);
    const [authenticated, setAuthenticated] = useState(false);
    const [msg, setMsg] = useState('');
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');


    const _handleEmail = (e) => {
        setEmail(e.target.value);
    };

    const _handlePass = (e) => {
        setPassword(e.target.value);
    };

    const _handleSubmit = async (e) => {
        e.preventDefault();
        loginUser(email, password);
        if (user) {
            console.log(user);
            this.props.onHandleUser(user);
        }
    };

return (
        <div className='splashStyle'>
            {!authenticated && (
                <Login
                    handleEmail={_handleEmail}
                    handlePass={_handlePass}
                    handleSubmit={_handleSubmit}
                    isAuthenticated={authenticated}
                />
            )}
        </div>
    );
};d

编辑:我的问题是 setAuthenticated、setUser、setEmail 和 setPassword 在 utils.js 中未定义

谢谢!

【问题讨论】:

  • 通常在应用程序中,用户登录后,他们希望重定向到另一个页面。为什么在您的情况下没有重定向功能?以及为什么在提交表单后需要重新初始化邮箱和密码。提交表单后,表单没有任何用途。

标签: reactjs state react-functional-component


【解决方案1】:

您需要在调用 setAuthenticated 函数之前将其传递给 loginUser 函数。

【讨论】:

  • 你说得对,但是他以后还是会因为这个关键字的使用而出问题,尝试在()中不输入props的情况下访问props
【解决方案2】:

从您的登录用户挂钩返回一个 onSubmiHandler 函数。


const doLogin = (email , password) => {

  /// your code here

}

return {doLogin}

然后在你的主组件中使用 doLogin 函数

  //inside functional component

  const {doLogin} = loginUser();

  
  onSubmit = () => doLogin(email, password)

您可以从这里了解如何使用自定义挂钩

https://reactjs.org/docs/hooks-custom.html

【讨论】:

    【解决方案3】:

    要启动 loginUser 无法知道您插入的 setState 尝试将其作为参数传递,它会修复它?

    我看到的另一个问题是您使用 this 关键字,而在功能组件中您只使用 props

    只是为了让您知道不要传递 null,因为初始值传递一个空字符串、数字等。 更新

    这也是您将 setState 作为参数传递的方式

     loginUser((e)=>setEmail(e)) 
    

    【讨论】:

    • 您是说通过 setAuthenticated、setEmail 等...作为参数?我该怎么做?是的..这是一项正在进行中的工作。在发布之前,我可能没有完全正确地编写代码。对不起!
    • 首先没关系大家问代码好坏没关系,我会编辑我的帖子
    【解决方案4】:

    实现此目的的一种方法是将所有 set 方法作为参数传递给 loginUser 函数。

    但更好的方法是:

    创建两个单独的文件

    1 用于登录 api 调用,例如:

    login.js

    function login(email, password){
        const login = await axios.post('http://localhost:5000/api/v1/auth/login', {
            email,
            password
        });
        return login.data;
    }
    

    另一个用于获取数据

    getProfile.js

    function getProfile(token){
        const options = {
            headers: {
                Authorization: `Bearer ${token}`
            }
        };
        const getUser = await axios.get(
            'http://localhost:5000/api/v1/auth/me',
            options
        );
        return getUser.data;
    }
    

    现在您是否在实际组件提交调用函数中设置状态内容,例如

    const _handleSubmit = async (e) => {
        e.preventDefault();
        const token = await login(email, password);
        const user = await getProfile(token);
        if (user) {
            console.log(user);
            props.onHandleUser(user);
            setAuthenticated(true);
            setUser(getUser.data.data);
            setEmail('');
            setPassword('');
    
            localStorage.setItem('user', JSON.stringify(user));
            console.log(localStorage.getItem('user'));
        }
    };
    

    【讨论】:

    • this.props.onHandleUser 是有问题的,因为在功能组件中你只需要使用 props 而不是 this.props,因为 this 是用于类组件的
    • @TalOrlanczyk 是的,你说得对,实际上我刚刚从问题中复制了这些行。现在我已经更新了我的答案,感谢您指出
    • 忘记告诉您向 const 用户添加 if 语句,因为他依赖于令牌他得到了令牌,这意味着用户存在我认为所以你只需要检查令牌(我不确定,所以如果你纠正我,我会很高兴)
    猜你喜欢
    • 1970-01-01
    • 2020-12-26
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2021-04-17
    • 2020-05-07
    • 1970-01-01
    相关资源
    最近更新 更多