使用fetch()的上下文API缩减程序不更新状态

我正在使用上下文API开发电子商务React应用程序中的登录函数。因此,当用户键入他的电子邮件和密码时,它会调用reducer中的操作来检查数据,并将用户数据设置为Context Provider中的状态。

下面是动作(我省略了其他可行的案例):

const reducer = (state, action) => {
...

switch(action.type) {
case 'USER_LOGIN': 
        let user = userLogin(state.user,action.payload);
        return {
          ...state,
          user: user,
          loggedIn: temp.length> 0 ? true: false
        };

...

下面是函数userLogin(),它本身运行良好,并返回一个很好的用户数据数组。

var userLogin = (user, payload) => {

  const url = "/api/users/login.php";
  console.log(payload);
  fetch(url,{
    method: "POST",
    body: JSON.stringify(payload)
  })
      .then(response => response.json())
      .then(
      (result) => {
          user.id = result.id;
          user.name = result.name;
          user.email = result.email;
          user.phone = result.phone;
          user.city = result.city;
          user.street = result.street;
          user.building = result.building;
          user.flat = result.flat;        
      },
      (error) => {
          console.log(error);
      }); 
  return user;
}

但是在我的<Provider>中,user的状态值在初始化时仍然是一个空数组。

我认为有一些东西必须与异步类型的fetch()一起工作,但找不到任何关于这方面的参考资料。

更新:这是我的<Login>组件

import React, { Component } from 'react'
import {Consumer} from '../../Context'


export default class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: "",
            password: "",
        };
    }

    userLogin = (dispatch, e) => {
        e.preventDefault();
        dispatch({
            type: 'USER_LOGIN',
            payload: {email: this.state.email,
                      password: this.state.password }
        });
    }

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

    render() {
        return (
            <Consumer>
            {
                value=> {
                    const {dispatch} = value;
                    return (
                        <div className="checkout__container">
                        <h5 className="checkout__header">Login</h5>
                        <form>
                            <label className="checkout__label">E-mail:</label><br />
                            <input className="checkout__input" type="email" name="email" onChange={this.handleChange}></input><br /><br />
                            <label className="checkout__label">Password:</label><br />
                            <input className="checkout__input" type="password" name="password" onChange={this.handleChange}></input><br /><br />
                            <button type="button" className="button button-primary" onClick={this.userLogin.bind(this, dispatch)}>Sign In</button>

                        </form> 
                        </div>
                    );
                }
            }


            </Consumer>
        )
    }
}

更新#2:下面是我的带有Provider组件的Context.js的摘录

import React, { Component } from 'react'
import axios from 'axios'

const Context = React.createContext();

const reducer = (state, action) => {
...
switch(action.type) {
case 'USER_LOGIN': 
        let user = userLogin(state.user,action.payload);
        return {
          ...state,
          user: user
        };
  }; 
};

var userLogin = (user, payload) => {
    // Do fetch() here and return user array
}
...
class Provider extends Component {
    constructor(props) {
        super(props);
        this.state = {
          user: [],
          loggedIn: false,
          dispatch: action => this.setState( state => reducer(state,action))         
        };
    }
 render() {
    return (
      <Context.Provider value={this.state}>
          {this.props.children}
      </Context.Provider>
    )
  }
}

const Consumer = Context.Consumer;

export {Provider, Consumer};

转载请注明出处:http://www.ahddzj.com/article/20230526/1131276.html