TypeError:无法读取未定义的属性“用户”|但用户已定义

Posted

技术标签:

【中文标题】TypeError:无法读取未定义的属性“用户”|但用户已定义【英文标题】:TypeError: Cannot read property 'users' of undefined | but users is defined 【发布时间】:2021-10-21 04:56:16 【问题描述】:

我现在遇到这个错误,我不知道为什么。

我知道错误行在此代码中,但我看不出我做错了什么。

const found = getState().usersState.users.some(el => el.uid === uid);

代码:

import  USER_STATE_CHANGE, USER_POSTS_STATE_CHANGE, USER_FOLLOWING_STATE_CHANGE, USERS_DATA_STATE_CHANGE  from "../constants/index";
import firebase from "firebase/app";
import 'firebase/firestore'

export function fetchUser()
    return ((dispatch) =>
        firebase.firestore()
            .collection("users")
            .doc(firebase.auth().currentUser.uid)
            .get()
            .then((snapshot) =>
                if(snapshot.exists)
                    dispatch(type: USER_STATE_CHANGE, currentUser: snapshot.data)
                else
                    console.log('does not exist')
            
        )
    )


export function fetchUserPosts()
    return ((dispatch) =>
        firebase.firestore()
            .collection("posts")
            .doc(firebase.auth().currentUser.uid)
            .collection("userPosts")
            .orderBy("creation", "asc")
            .get()
            .then((snapshot) =>
                let posts = snapshot.docs.map(doc => 
                    const data = doc.data();
                    const id = doc.id;
                    returnid, ...data
           )
           dispatch(type: USER_POSTS_STATE_CHANGE, posts)
        )
    )


export function fetchUserFollowing()
    return ((dispatch) =>
        firebase.firestore()
            .collection("following")
            .doc(firebase.auth().currentUser.uid)
            .collection("userFollowing")
            .onSnapshot((snapshot) =>
                let following = snapshot.docs.map(doc => 
                    const id = doc.id;
                    return id
           )
           dispatch(type: USER_FOLLOWING_STATE_CHANGE, following)
           for(let i = 0; i < following.length; i++)
                dispatch(fetchUsersData(following[i]));
           
        )
    )



export function fetchUsersData(uid) 
    return ((dispatch, getState) => 
        const found = getState().usersState.users.some(el => el.uid === uid);
        if (!found) 
            firebase.firestore()
                .collection("users")
                .doc(uid)
                .get()
                .then((snapshot) => 
                    if (snapshot.exists) 
                        let user = snapshot.data();
                        user.uid = snapshot.id;

                        dispatch( type: USERS_DATA_STATE_CHANGE, user );
                    
                    else 
                        console.log('does not exist')
                    
                )
                if(getPosts)
                    dispatch(fetchUsersFollowingPosts(uid));
                
        
    )


export function fetchUsersFollowingPosts(uid) 
    return ((dispatch, getState) => 
        firebase.firestore()
            .collection("posts")
            .doc(uid)
            .collection("userPosts")
            .orderBy("creation", "asc")
            .get()
            .then((snapshot) => 
                const uid = snapshot.query.EP.path.segments[1];
                const user = getState().usersState.users.find(el => el.uid === uid);


                let posts = snapshot.docs.map(doc => 
                    const data = doc.data();
                    const id = doc.id;
                    return  id, ...data, user 
                )

                for(let i = 0; i< posts.length; i++)
                    dispatch(fetchUsersFollowingLikes(uid, posts[i].id))
                
                dispatch( type: USERS_POSTS_STATE_CHANGE, posts, uid )

            )
    )

这是我在 reducers 文件夹中的内容:

index.js:

import  combineReducers  from 'redux'
import  user  from './user'
import  users  from './users'


const Reducers = combineReducers(
    userState: user,
    userState: users
)

export default Reducers

user.js:

import  USER_STATE_CHANGE, USER_POSTS_STATE_CHANGE, USER_FOLLOWING_STATE_CHANGE  from "../constants"

const initialState = 
    currentUser: null,
    posts: [],
    follwing: [],


export const user = (state = initialState, action) => 
    switch (action.type) 
        case USER_STATE_CHANGE:
            return 
                ...state,
                currentUser: action.currentUser
            
        case USER_POSTS_STATE_CHANGE:
            return 
                ...state,
                posts: action.posts
            

        case USER_FOLLOWING_STATE_CHANGE:
            return 
                ...state,
                following: action.following
            
            default:
                return state
    
    

users.js:

import  USERS_POSTS_STATE_CHANGE, USERS_DATA_STATE_CHANGE  from "../constants"

const initialState = 
    users: null,
    userLoaded: 0,


export const users = (state = initialState, action) => 
    switch (action.type) 
        case USERS_DATA_STATE_CHANGE:
            return 
                ...state,
                users: [...state.users, action.users]
            
        case USERS_POSTS_STATE_CHANGE:
            return 
                ...state,
                usersLoaded: state.userLoaded + 1,
                users: state.users.map(user => user.uid === action.uid ?...user, posts: action.posts :
                user)      
            

        
            default:
                return state
    
    

【问题讨论】:

请出示您的减速机 你必须先提供你的 reducer,然后才能有人帮忙,因为 user state 是在你的 reducer 中定义的。 @Viet 已上传,希望对您有所帮助! @Delice 希望这会有所帮助! 【参考方案1】:

问题就在这里:

const found = getState().usersState.users.some(el => el.uid === uid);

这里的users 来自异步请求,在第一次渲染时不可用。因此,您必须进行如下检查:

if( getState().usersState && getState().usersState.users )  // Access it when it is available

  const found = getState().usersState.users.some(el => el.uid === uid);

const found = ( getState().usersState && getState().usersState.users ) ? getState().usersState.users.some(el => el.uid === uid): [];

类似的东西。试试这个,错误就会消失,你会得到数据。

【讨论】:

谢谢@Mayank!我不得不使用你的和 Viets 他的,现在它正在工作!谢谢! 请将getState().usersState 提取到变量中。这对我来说太多了 @Delice 对,最好将它存储在一个变量中,并在所有需要它的地方使用该变量。【参考方案2】:

也许 firebase 仍在获取用户,您可以使用可选链接 ? 来保护这种行为。试试这个

const found = getState().usersState?.users?.some(el => el.uid === uid);

【讨论】:

【参考方案3】:

您在combineReducers 中写错了。 usersState 而不是 userState

const Reducers = combineReducers(
    userState: user,
    usersState: users
)

【讨论】:

...或者他拼错了他的状态:D @Delice 是她哈哈 @Viet 这有帮助,但我不得不将您的答案与 Mayank 他的答案结合起来,然后它就奏效了!谢谢! :)

以上是关于TypeError:无法读取未定义的属性“用户”|但用户已定义的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ReactStrap 中使用 innerRef ? #TypeError:无法读取未定义的属性“用户名”

TypeError:无法读取未定义 Firebase 存储反应的属性“参考”

错误:TypeError:尝试为网站 node.js 注册用户时无法读取未定义的属性“catch”

TypeError:无法读取 Vue 中未定义的属性“id”

REACT JS:TypeError:无法读取未定义的属性“参数”

TypeError:无法读取未定义的属性“历史”