React Redux 道具未定义 [英] React Redux prop is undefined

查看:56
本文介绍了React Redux 道具未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

初学者问题.我想将用户对象作为道具从商店传递给组件,但组件没有得到它(未定义).我从第三方服务身份验证服务 (google firebase) 获取用户对象

中间件实际上在控制台中注销了 SET_CURRENT_USER 类型的操作发生,并且下一个状态确实会将 user.currentUser 设置为从登录服务返回的对象(未定义).

但是,组件不会重新渲染,并且似乎不会将对象作为道具接收

未定义 prop 的组件

从'react'导入React;从'react-redux'导入{连接};从../../firebase/firebase.utils"导入 { auth };export const Navbar = ({ currentUser }) =>{返回 (/* 很多 JSX 代码.当前用户未定义 */);};const mapStateToProps = state =>({当前用户:state.user.currentUser});导出默认连接(mapStateToProps)(导航栏);

App 组件,将上述组件作为子组件.另外,我试图将商店设置为在 componentDidMount()

中包含用户对象

从'react'导入React;从./pages/homepage"导入主页;从'react-router-dom'导入{路由,开关};从'react-redux'导入{连接};从./pages/login"导入登录;从./pages/register"导入注册;import { Navbar } from "./components/navbar/navbar";从./firebase/firebase.utils"导入 { auth };import { setCurrentUser } from "./redux/user/user.actions";类 App 扩展了 React.Component {unsubscribeFromAuth = null;componentDidMount() {this.unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => {如果(用户身份验证){(异步() => {const rawResponse = await fetch(/* 只是一个异步函数来发布到后端*/);})();}this.props.setCurrentUser(userAuth);/*这里我正在尝试设置商店*/})}componentWillUnmount() {this.unsubscribeFromAuth();}使成为() {返回 (<div><导航栏/>/* 应该获取用户对象作为道具的组件 */<开关><路由精确={true} path={'/register'} component={Register}/><路由精确={true} path={'/login'} component={Login}/><Route path={'/'} component={Homepage}/></开关>

);}}const mapDispatchToProps = (调度) =>({setCurrentUser: 用户 =>调度(设置当前用户(用户))});导出默认连接(空,mapDispatchToProps)(应用程序);

索引组件

从'react'导入React;从 'react-dom' 导入 ReactDOM;从./App"导入应用程序;从react-router-dom"导入 { BrowserRouter };从'react-redux'导入{提供者};从./redux/store"导入商店;ReactDOM.render(<提供者商店={商店} >/* 这里是从进口提供的商店*/<浏览器路由器><应用程序/></BrowserRouter></提供者>,document.getElementById('root'));

根减速器

import { combineReducers } from "redux";导出默认的 combineReducers({用户:userReducer});

用户减速器

const INITIAL_STATE = {当前用户:空};const userReducer = (state = INITIAL_STATE, action) =>{开关(动作.类型){案例SET_CURRENT_USER":返回 {...状态,当前用户:action.payload};默认:返回状态;}};导出默认的 userReducer;

用户操作

export const setCurrentUser = user =>({类型:'SET_CURRENT_USER',有效载荷:用户});

店铺

import { createStore, applyMiddleware } from "redux";从redux-logger"导入记录器;从'./root-reducer'导入rootReducer;const 中间件 = [记录器];const store = createStore(rootReducer, applyMiddleware(...middlewares));导出默认商店;

解决方案

您正在为 Navbar 执行 nameddefault 导出.默认导出由 connect HOC 包装,该 HOC 将 currentUser 添加到其 props.命名导出没有.

您导入它,命名如下:import { Navbar } from.而是使用默认导出:import Navbar from.

那么我建议删除命名导出以避免将来混淆.

Beginner question. I want to pass a user object to a component from store as a prop, but the component doesn't get it (undefined). I get the user object from a third party service authentication service (google firebase)

The middleware actually logs out in the console that the action of type SET_CURRENT_USER takes place, and next state indeed will have a user.currentUser set to the object returned from the login service (NOT UNDEFINED).

However, the component doesn't re-render and doesn't seem to receive the object as prop

The component, in which the prop is undefined

import React from 'react';
import { connect } from 'react-redux';
import { auth } from "../../firebase/firebase.utils";

export const Navbar = ({ currentUser }) => {
    return (
        /* A LOT OF JSX CODE. currentUser IS UNDEFINED */
    );
};

const mapStateToProps = state => ({
    currentUser: state.user.currentUser
});

export default connect(mapStateToProps)(Navbar);

The App component, which has the above component as a child. Also, I'm trying to set the store to contain the user object in the componentDidMount()

import React from 'react';
import Homepage from "./pages/homepage";
import { Route, Switch } from 'react-router-dom';
import { connect } from 'react-redux';

import Login from "./pages/login";
import Register from "./pages/register";
import { Navbar } from "./components/navbar/navbar";

import { auth } from "./firebase/firebase.utils";
import { setCurrentUser } from "./redux/user/user.actions";

class App extends React.Component {
    unsubscribeFromAuth = null;

    componentDidMount() {
        this.unsubscribeFromAuth = auth.onAuthStateChanged(async userAuth => {
            if(userAuth) {
                (async () => {
                    const rawResponse = await fetch(/* JUST AN ASYNC FUNCTION TO POST TO BACKEND*/);
                })();
            }
            this.props.setCurrentUser(userAuth); /*HERE IM TRYING TO SET THE STORE*/
        })
    }

    componentWillUnmount() {
        this.unsubscribeFromAuth();
    }

    render() {
        return (
            <div>
                <Navbar /> /* THE COMPONENT WHICH SHOULD GET THE USER OBJECT AS PROP */
                <Switch>
                    <Route exact={true} path={'/register'} component={Register} />
                    <Route exact={true} path={'/login'} component={Login} />
                    <Route path={'/'} component={Homepage} />
                </Switch>
            </div>
        );
    }
}

const mapDispatchToProps = (dispatch) => ({
    setCurrentUser: user => dispatch(setCurrentUser(user))
});

export default connect(null, mapDispatchToProps)(App);

The index component

import React from 'react';
import ReactDOM from 'react-dom';
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import { Provider } from 'react-redux';

import store from "./redux/store";

ReactDOM.render(
    <Provider store={store} > /* HERE IS STORE PROVIDED FROM IMPORT*/
        <BrowserRouter>
            <App/>
        </BrowserRouter>
    </Provider>,
    document.getElementById('root')
);

Root reducer

import { combineReducers } from "redux";

export default combineReducers({
    user: userReducer
});

User reducer

const INITIAL_STATE = {
    currentUser: null
};

const userReducer = (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case 'SET_CURRENT_USER':
            return {
                ...state,
                currentUser: action.payload
            };
        default:
            return state;
    }
};

export default userReducer;

User action

export const setCurrentUser = user => ({
    type: 'SET_CURRENT_USER',
    payload: user
});

The store

import { createStore, applyMiddleware } from "redux";
import logger from 'redux-logger';

import rootReducer from './root-reducer';

const middlewares = [logger];

const store = createStore(rootReducer, applyMiddleware(...middlewares));

export default store;

解决方案

You're doing both a named and default export for Navbar. The default export gets wrapped by the connect HOC that adds currentUser to its props. The named export does not.

You import it named like this: import { Navbar } from. Instead use the default export: import Navbar from.

Then I would suggest removing the named export to avoid future confusion.

这篇关于React Redux 道具未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆