React Redux 道具未定义 [英] React Redux prop is undefined
问题描述
初学者问题.我想将用户对象作为道具从商店传递给组件,但组件没有得到它(未定义).我从第三方服务身份验证服务 (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
执行 named 和 default 导出.默认导出由 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屋!