声明状态属性的组件是未定义的,即使它是,Auth

Posted

技术标签:

【中文标题】声明状态属性的组件是未定义的,即使它是,Auth【英文标题】:Component claiming state prop is undefined eventhough it is, Auth 【发布时间】:2017-08-21 22:37:33 【问题描述】:

我正在尝试注销用户并显示注册/登录 div 或配置文件部分,具体取决于用户是否登录,我尝试在我的主应用程序上呈现的组件上执行此操作。

使用 ReduxDevTools 我可以看到当我登录用户时身份验证状态会发生变化,但是当我尝试呈现 LeftContainer 设置身份验证时:state.auth 我得到身份验证未定义,

错误:

无法读取未定义的属性“isAuthenticated” 警告:失败的道具类型:道具authLeftContainer中标记为必填,但其值为undefined


LeftContainerProfile/index.js

import React from 'react';
import  FormattedMessage  from 'react-intl';
import  Link  from 'react-router'
import  connect  from 'react-redux';
import  logout  from '../../containers/SignIn/authActions';
import styled from 'styled-components';

import Logo from '../Logo/Logo';
import SocialLinks from '../SocialLinks/social_links';
import ProfileContainer from './profile';
import LinksContainer from './about_links';


const Wrapper = styled.div`
  position: absolute;
  top: 250px;
  width: 20%;
  padding-left: 4%;
  padding-right: 4%;
  // height:  100vh;

`;

const Button = styled(Link)`
  width: 100px;
  height: 50px;
  background-color: red;
  color: white;
  margin: 5px;
`;

class LeftContainer extends React.Component  // eslint-disable-line react/prefer-stateless-function
  logout(e) 
    e.preventDefault();
    this.props.logout();
  


  render() 

    const  isAuthenticated  = this.props.auth;

    const userLinks = (
      <div>
        <ProfileContainer />
        <Button onClick=this.logout.bind(this)> LOGOUT </Button>
      </div>
    );

    const guestLinks = (
       <div>
            <Button to='/login'>LOGIN</Button>
            <Button to='/sign-up'>REGISTER</Button>
       </div> 
    );

    return (

          <Wrapper>

             isAuthenticated ? userLinks : guestLinks 

             <LinksContainer />
             <SocialLinks />
          </Wrapper>
    );
  


LeftContainer.propTypes = 
  auth: React.PropTypes.object.isRequired,
  logout: React.PropTypes.func.isRequired


function mapStateToProps(state) 
  return 
    auth: state.auth
  ;


export default connect(mapStateToProps,  logout )(LeftContainer);

我正在尝试获取身份验证的状态,但我得到未定义或对象

这是一张来自 reduxdevtools 的图片https://gyazo.com/b189a75e1123cb198412adf93bdd3497


编辑 3:当我这样做时

function mapStateToProps(state) 
  console.log(state);
  return 
    isAuthenticated: state.auth 
  ;

我明白了 https://gyazo.com/432247229816e4a68a50133834b551c9

也许这会帮助人们找到解决我问题的方法


编辑 4:我找到了一个解决方案,但我不确定这是否是解决此问题的正确方法,有人可以解释为什么 state.auth 没有给出我想要的结果,是我的减速器中的东西还是其他东西?这是我的解决方案

class LeftContainer extends React.Component  // eslint-disable-line react/prefer-stateless-function

  logout(e) 
    e.preventDefault();
    this.props.logout();
  



  render() 

    const  isAuthenticated  = this.props;

    const userLinks = (
      <div>
        <ProfileContainer />
        <Button onClick=this.logout.bind(this)> LOGOUT </Button>
      </div>
    );

    const guestLinks = (
       <div>
            <Button to='/login'>LOGIN</Button>
            <Button to='/sign-up'>REGISTER</Button>
       </div> 
    );

    return (

          <Wrapper>
             isAuthenticated ? userLinks : guestLinks 
               <div>
            /*<Button to='/login'>LOGIN</Button>
            <Button to='/sign-up'>REGISTER</Button>*/
       </div> 
             <LinksContainer />
             <SocialLinks />
          </Wrapper>
    );
  


// LeftContainer.propTypes = 
//   auth: React.PropTypes.object.isRequired,
//   logout: React.PropTypes.func.isRequired
// 

    // LeftContainer.propTypes = 
    //   isAuthenticated: React.PropTypes.bool.isRequired,
    //   logout: React.PropTypes.func.isRequired
    // 
    // LeftContainer.defaultProps = 
    //     isAuthenticated: true,
    // 

    function mapStateToProps(state) 
      console.log(state._root.entries[3][1].isAuthenticated);
      return 
        isAuthenticated: state._root.entries[3][1].isAuthenticated
      ;
    

    export default connect(mapStateToProps,  logout )(LeftContainer);

【问题讨论】:

可能在组件第一次渲染时auth prop 没有被赋予任何值。并且只有在第二次渲染时才会填充道具。如果 prop 有值,请尝试检查您的渲染函数,然后才在渲染逻辑中使用它。 我该怎么做呢,我还是很陌生。 你可能想看看Component Lifecycle,尤其是componentWillReceiveProps方法并记录你的props。 【参考方案1】:

或者一种更简单的方法(比我在评论中列出的方法):

我直接从mapeStateToProps 函数处理了isAuthenticated,并将其设为bool 值以提高可读性。这不太容易出错,因为您不会在 props 上传递嵌套对象。作为后备,我添加了一个 defaultProp 值。

希望这能解决问题。

class LeftContainer extends React.Component  // eslint-disable-line react/prefer-stateless-function
      logout(e) 
        e.preventDefault();
        this.props.logout();
      


      render() 

        const  isAuthenticated  = this.props;

        const userLinks = (
          <div>
            <ProfileContainer />
            <Button onClick=this.logout.bind(this)> LOGOUT </Button>
          </div>
        );

        const guestLinks = (
           <div>
                <Button to='/login'>LOGIN</Button>
                <Button to='/sign-up'>REGISTER</Button>
           </div> 
        );

        return (

              <Wrapper>

                 isAuthenticated ? userLinks : guestLinks 

                 <LinksContainer />
                 <SocialLinks />
              </Wrapper>
        );
      
    

    LeftContainer.propTypes = 
      isAuthenticated: React.PropTypes.bool.isRequired,
      logout: React.PropTypes.func.isRequired
    
    LeftContainer.defaultProps = 
        isAuthenticated: false,
    

    function mapStateToProps(state) 
      return 
        isAuthenticated: state.auth && state.auth.isAuthenticated
      ;
    

    export default connect(mapStateToProps,  logout )(LeftContainer);

【讨论】:

以上是关于声明状态属性的组件是未定义的,即使它是,Auth的主要内容,如果未能解决你的问题,请参考以下文章

单个文件组件vue js上的属性this.$el未定义

useContext 返回未定义,即使它不应该是未定义的

React BrowserRouter:位置未定义

i += ++i 在 C++0x 中是未定义的行为吗?

为啥没有用户ID?它是未定义的

req.user 是未定义的,即使它能够 console.log 用户