我正在学习如何使用Redux,并且在设置动作和缩减器时遇到了问题。这是我的设置:
行动在这里:
export const loginUser = (test) => {
return {
type:'loginUser',
loggedIn:true
}
}
export const toggleRegLog = (test) => {
return {
type:'toggleRegLog',
}
}
减速器在这里:
let initialState = [];
const userAuthReducer = (state = initialState,action) => {
switch (action.type) {
case 'loginUser':
let newState = [...state];
if(action.loggedIn) {
newState = "logged-in";
} else {
newState = "not-logged-in";
}
return newState;
break;
case:'toggleRegLog':
let newState = [...state];
return action.state;
break;
default:
return state;
}
}
export default userAuthReducer;
reducers的组合在一个名为index的文件中:
import {combineReducers} from 'redux';
import userAuthReducer from './reducers/userAuthReducer';
function lastAction(state = null, action) {
return action;
}
export default combineReducers({
userAuthReducer
});
演示组件:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import { bindActionCreators } from 'redux';
import * as authActions from './actions/userAuthActions';
class App extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log(this.props)
}
render() {
return (
<div>
<button onClick={this.props.loginUser()}></button>
</div>
);
}
const mapStateToProps = (state) => {
return {
userAuthReducer:state.userAuthReducer
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(authActions,dispatch);
};
export default connect(mapStateToProps,mapDispatchToProps)(App);
}
我之前以一种更基本的方式让国家工作但是在看了一些更多的教程并决定引入单独的动作创建者(即不仅仅是从我的组件直接调度到减速器)并在我的减速器中引入多个案例它似乎不再起作用了。我的组件上的console.log(this.props)
将操作作为函数返回,并将状态返回为undefined。
有人能找到我出错的地方吗?
答案 0 :(得分:4)
您在此项目设置中遇到了很多错误。
如果您正在运行发布的代码
,您应该会看到它们常数 (错过)
常量对于增加动作和缩减器的一致性非常重要。
export const LOGIN_USER = 'loginUser';
export const TOGGLE_REG_LOG = 'toggleRegLog';
<强> 操作 强>
您的行为没有任何问题,只是一些建议
import { LOGIN_USER, TOGGLE_REG_LOG } from '../constants/userAuthConstants';
export const loginUser = (loggedIn = true) => {
return {
type: LOGIN_USER,
payload: {
loggedIn
}
}
}
export const toggleRegLog = () => {
return {
type: TOGGLE_REG_LOG,
}
}
<强> 减速 强>
case: toggleRegLog:
声明中有错误。
建议:
Object.assign
代替传播运营商newState
import { LOGIN_USER, TOGGLE_REG_LOG } from '../constants/userAuthConstants';
const initialState ={
userLoginStatus: 'not-logged-in'
};
const userAuthReducer = (state = initialState, action) => {
switch (action.type) {
case LOGIN_USER: {
const userLoginStatus = action.payload.loggedIn ? 'logged-in' : 'not-logged-in';
const newState = Object.assign(state, {
userLoginStatus
});
return newState;
}
case TOGGLE_REG_LOG: {
let newState = Object.assign({}, state, {}); // do what you need here
return newState;
}
default:
return state;
}
}
export default userAuthReducer;
<强> 组件 强>
当您在按钮中附加onClick
事件时,正在执行loginUser
函数时,它正在期待函数回调,而是在不执行它的情况下传递loginUser
,因此当用户单击时按钮动作将被分派
建议:
constructor
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { loginUser } from './actions/userAuthActions';
class App extends Component {
componentDidMount() {
console.log(this.props);
}
render() {
const { userLoginStatus, loginUser } = this.props;
return (
<div>
<p> User status: {userLoginStatus}</p>
<button onClick={loginUser}>click me</button>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
userLoginStatus: state.userAuthReducer.userLoginStatus
};
};
const mapDispatchToProps = (dispatch) => {
return {
loginUser: () => dispatch(loginUser())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
在开始测试任何库/框架之前,请确保您遵循最佳实践,并且您的代码不包含任何错误,否则您可能会开始使用代码做恶梦。
答案 1 :(得分:0)
操作:这里我已经将newState有效负载添加到了在reducer中使用的操作。
export const loginUser = () => {
return {
type:'loginUser',
loggedIn:true
}
}
export const toggleRegLog = () => {
return {
type:'toggleRegLog',
newState: xyz, //whatever you want it to be
}
}
减速: 在这里,我将您的初始状态更改为json对象,该对象具有loginStatus的字段。您可以使用同一个对象通过添加其他字段来跟踪其他内容。我已将字段的初始状态设置为&#34; not-logged-in&#34;。在reducer中,使用spread运算符将initail状态扩展到一个新对象中,并覆盖要更新的字段。
let initialState = {
loginStatus:"not-logged-in",
//other stuff
};
const userAuthReducer = (state = initialState,action) => {
switch (action.type) {
case 'loginUser':
let newState = {};
if(action.loggedIn) {
newState = {...state, loginStatus:"logged-in"};
} else {
newState = {...state, loginStatus:"not-logged-in"};
}
return newState;
break;
case:'toggleRegLog':
return {...state, loginStatus:action.newState};
break;
default:
return state;
}
}
export default userAuthReducer;
App组件:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import { bindActionCreators } from 'redux';
import * as authActions from './actions';
class App extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log(this.props)
}
render() {
return (
<div>
<button onClick={this.props.loginUser}></button>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
userAuthReducer:state.userAuthReducer
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(authActions,dispatch);
};
export default connect(mapStateToProps,mapDispatchToProps)(App);