如何获取导入的功能以设置功能组件的状态?

时间:2020-09-19 18:43:28

标签: reactjs state react-functional-component

我有一个带有较长的onSubmit函数的react类组件,为了使代码更整洁,我将其放到另一个文件中。

我试图将类组件转换为功能组件,将所有state和setState函数替换为useState,但是现在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

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

谢谢!

4 个答案:

答案 0 :(得分:0)

您需要先将 setAuthenticated 函数传递给 loginUser 函数,然后再调用该函数。

答案 1 :(得分:0)

从登录用户挂钩中返回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

答案 2 :(得分:0)

要启动 loginUser ,您可能不知道 setState ,请在其中插入尝试将其作为参数传递并将其修复?

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

,并且您要知道不要传递null,因为初始值传递的是空字符串,数字等。 更新

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

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

答案 3 :(得分:0)

一种实现方法是将所有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'));
    }
};