为什么使用重复的嵌套键更新 Redux 存储

Why is the Redux store being updated with a duplicate nested key?

本文关键字:更新 Redux 存储 嵌套 为什么      更新时间:2023-09-26

我从React和Redux开始,所以我将一个组件连接到Redux存储,我得到了这个组件,它应该是一个非常简单的登录:

import React, { Component } from 'react';
import { findDOMNode } from "react-dom";
import RaisedButton from 'material-ui/lib/raised-button';
import TextField from 'material-ui/lib/text-field';
import { connect } from 'react-redux';
import { loginRequest, loginSuccess, loginFailure } from '../actions';
import { browserHistory } from 'react-router';
class LoginForm extends Component {
  componentDidMount() {
    console.log(console.log(JSON.stringify(this.props,null,2)));
  }
  readyToSubmit() {
  }
  onSubmit(e) {
      e && e.preventDefault();
      let emailInput = findDOMNode(this.refs.emailInput).querySelector("input").value;
      let passwordInput = findDOMNode(this.refs.passwordInput).querySelector("input").value;
      if (emailInput.trim().length && passwordInput.trim().length) {
        if (emailInput.startsWith('hello')) {
          this.props.loginSuccess(emailInput);
        } else {
          console.log(emailInput);
          this.props.loginFailure(emailInput);
        }
      }
  }
  render() {
      let disabled = !!this.props.login.waiting || !!this.props.ready;
      return (
          <form onSubmit={::this.onSubmit}>
          <div>
            <TextField hint="E-mail" floatingLabelText="E-mail" ref="emailInput" onChange={::this.readyToSubmit}></TextField><br/>
          </div>
          <div>
            <TextField hint="Contraseña" floatingLabelText="Contraseña" type="password" ref="passwordInput" onChange={::this.readyToSubmit}></TextField><br/><br/>
          </div>
          <div>
            <RaisedButton type="submit" label="Acceder" primary={true} disabled={disabled} onClick={::this.onSubmit}/>
          </div>
        </form>
      );
  }
}
export default connect(
  state => {
    return {
      login: state.login
    }
  },
  {
    loginSuccess: loginSuccess,
    loginFailure: loginFailure,
    loginRequest: loginRequest
  })(LoginForm);

这些是操作:

export const loginSuccess = (email) => {
  return {type: 'LOGIN_SUCCESS', email: email };
}
export const loginFailure = (email) => {
  return {type: 'LOGIN_FAILURE', email: email };
}
export const loginRequest = (email) => {
  return {type: 'LOGIN_REQUEST', email: email};
}

这些是我的减速器:

const login = (state = {}, action) => {
  switch (action.type) {
    case 'LOGIN_REQUEST':
      return {
        ...state.login,
        login: {
          waiting: true,
          email: action.email
        }
      };
      break;
    case 'LOGIN_SUCCESS':
      return {
          ...state.login,
          login: {
            waiting: false,
            email: action.email,
          },
          auth: {
            token: state.token
          }
      };
      break;
      case 'LOGIN_FAILURE':
        return {
            ...state.login,
            login: {
              waiting: false,
              email: action.email,
              errors: action.errors
            }
          };
        break;
    default:
      return {
        ...state.login,
        login: {
          ready: false
        }
      };
  }
}
export default login

所以,我注意到的第一个奇怪的东西是componentDidMount日志:

{
  "login": {
    "login": {
      "ready": false
    }
  }
}

所以我需要一些帮助:

  • 我不知道为什么嵌套的方式(login.login)。
  • 我想仅在填写密码和电子邮件字段时禁用该按钮。
  • 我知道 Redux 会避免我使用 React 的 state ,并且连接函数将组件属性的一些存储属性和一些调度程序也与属性联系起来......但是我如何才能轻松地访问字段、按钮等值作为道具的一部分。
  • 如何确保减速器实现真正的深度合并?
我认为

它很可能是你的化简器,而不是这个:

case 'LOGIN_REQUEST':
    return {
        ...state.login,
        login: {
            waiting: true,
            email: action.email
        }
    };
break;

试试这个:

case 'LOGIN_REQUEST':
    return {
        ...state, <-- removed the .login from here
        login: {
            waiting: true,
            email: action.email
        }
    };
break;

或者:

case 'LOGIN_REQUEST':
    return {
        ...state.login,
        //<-- removed the login key from the object you add to state.login
            waiting: true,
            email: action.email
    };
break;

让我们知道这是否有帮助:)

写以下内容:

state => {return state.login} 

而不是

export default connect(
 state => {
   return {
   login: state.login
 }