【问题标题】:Why doesn't my function action get called?为什么我的函数动作没有被调用?
【发布时间】:2020-04-15 14:09:10
【问题描述】:

我正在尝试注册用户。在我的组件文件中有填充状态的字段,然后在提交时它应该调用在操作中创建的注册函数,然后应该分派响应数据并在成功时键入注册成功,否则注册失败并分派错误。关键是填写必填字段并单击注册按钮后根本不会调用该函数。在检查网络中没有显示任何要调用的函数。我是第一次使用 webpack,也许这是此类问题的必要细节。

这是组件:

const Register = ({register}) => {
    const [formData, setFormData] = useState({
        first_name: '',
        last_name: '',
        email: '',
        phone: '',
        password: '',
        privacy: false
    });

    const {privacy} = formData;

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

    const onRegister = (e) => {
        e.preventDefault();
        if (privacy){
            console.log('kari');
            register(formData);
        } else {
            console.log('error');
        }
    };

    const onPrivacyCheck = () => {
        setFormData({...formData, privacy: !privacy})
    };

    return (
        <Fragment>
            <div>
                <h1>Register</h1>
                <form onSubmit={e => onRegister(e)}>
                    <input type={'text'} name={'first_name'} onChange={e => onChange(e)}/>
                    <input type={'text'} name={'last_name'} onChange={e => onChange(e)}/>
                    <input type={'text'} name={'phone'} onChange={e => onChange(e)}/>
                    <input type={'text'} name={'email'} onChange={e => onChange(e)}/>
                    <input type={'password'} name={'password'} onChange={e => onChange(e)}/>
                    <br/>
                    <input type={'checkbox'} name={'privacy'} checked={privacy}
                           onClick={() => onPrivacyCheck()}/>
                    <label htmlFor="checkbox">Privacy Policy</label>
                    <br/>
                    <input type={"submit"} value={'Register'}/>
                </form>
            </div>
        </Fragment>
    )
};

Register.propTypes = {
    register: PropTypes.func.isRequired
};

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

export default connect(mapStateToProps, {register})(Register);

这是行动:

export const register = (data) => async dispatch => {
    console.log(data);

    const config = {
        headers: {
            'Content-Type': 'application/json'
        }
    };

    const body = JSON.stringify(data);

    try {
        const res = await axios.post('http://localhost:5000/api/users', body, config);

        dispatch({
            type: REGISTER_SUCCESS,
            payload: res.data
        });

        dispatch(setAlert('User registered successfully!', 'success'));
    } catch (e) {
        const errors = e.response.data.errors;

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

        dispatch({
            type: REGISTER_FAIL
        });
    }
};

这是减速器:

import {
    REGISTER_SUCCESS,
    REGISTER_FAIL,
    USER_LOADED,
    AUTH_ERROR,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
    LOGOUT
} from "../actions/types";

const initialState = {
    token: localStorage.getItem('token'),
    isAuthenticated: null,
    loading: true,
    user: null
};

export default function (state = initialState, action) {
    const {type, payload} = action;

    switch (type) {
        case USER_LOADED:
            return {
                ...state,
                isAuthenticated: true,
                loading: false,
                user: payload
            };
        case REGISTER_SUCCESS:
        case LOGIN_SUCCESS:
            localStorage.setItem('token', payload.token);
            return {
                ...state,
                ...payload,
                isAuthenticated: true,
                loading: false
            };
        case REGISTER_FAIL:
        case AUTH_ERROR:
        case LOGIN_FAIL:
        case LOGOUT:
            localStorage.removeItem('token');
            return {
                ...state,
                token: null,
                isAuthenticated: false,
                loading: false
            };
        default:
            return state;
    }
}

【问题讨论】:

  • 你不应该像你那样在动作创建者中做任何副作用。我想,redux-thunk 中间件对于你的动作创建者使用 axios 发出请求是必要的。
  • 对我来说似乎有问题的另一件事是您将mapDispatchToProps 连接到您的组件的方式。如果您希望触发onRegister,您应该指定const mapDispatchToProps = dispatch =&gt; ({onRegister: data =&gt; dispatch(register(data))}),或者类似的东西并执行connect(mapStateToProps, mapDispatchToProps)(Register)

标签: reactjs webpack redux


【解决方案1】:

好的,我的解决方案是,制作你的组件类,安排你的功能 - 在需要的地方添加 thisthis.setState 并在你的操作中调用 registerData 函数:

import React, { Component, Fragment } from "react";
import {registerData} from "//Where the action file is"

class Register extends Component  {
    state= {
        first_name: '',
        last_name: '',
        email: '',
        phone: '',
        password: '',
        privacy: false
    };


    onChange = e => {
        this.setState({[e.target.name]: e.target.value})
    };

    onRegister = (e) => {
        e.preventDefault();
        if (this.state.privacy){
            console.log('kari');
            this.props.registerData(formData);
        } else {
            console.log('error');
        }
    };

    onPrivacyCheck = () => {
        this.setState({ privacy: !privacy})
    };
   render() {
    return (
        <Fragment>
            <div>
                <h1>Register</h1>
                <form onSubmit={this.onRegister}>
                    <input type={'text'} name={'first_name'} onChange={e => onChange(e)}/>
                    <input type={'text'} name={'last_name'} onChange={e => onChange(e)}/>
                    <input type={'text'} name={'phone'} onChange={e => onChange(e)}/>
                    <input type={'text'} name={'email'} onChange={e => onChange(e)}/>
                    <input type={'password'} name={'password'} onChange={e => onChange(e)}/>
                    <br/>
                    <input type={'checkbox'} name={'privacy'} checked={privacy}
                           onClick={() => this.onPrivacyCheck()}/>
                    <label htmlFor="checkbox">Privacy Policy</label>
                    <br/>
                    <input type={"submit"} value={'Register'}/>
                </form>
            </div>
        </Fragment>
    )
 }
};

Register.propTypes = {
    register: PropTypes.func.isRequired
};

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



export default connect(mapStateToProps, {registerData})(Register);

在你的表单中这样写 onSubmit 函数:

 <form onSubmit={this.onRegister}>

修改您的操作:

   export const registerData = data => dispatch => {
      const config = {
            headers: {
                'Content-Type': 'application/json'
            }
        };
      axios
        .post('http://localhost:5000/api/users', data, config)
        .then(res => {
          dispatch({
            type: REGISTER_SUCCESS,
            payload: res.data
          });;
        })
        .catch(err => {
          dispatch({
            type: SET_ERRORS,
            payload: err.response
          });
        });
    };

这应该可以工作

【讨论】:

  • OP 的Register 是一个函数组件,所以应该没有this。不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 2017-02-17
  • 2020-03-18
相关资源
最近更新 更多