因此,我是Redux的新手,我正在尝试使该基本模型正常工作,以便可以快速处理一个小型个人项目,我进行了所有设置,没有任何错误,但是我正在尝试测试和实现我的功能没有用,所以我希望有人可以指出我错过的事情。
我遵循了多个不同的教程,每个教程都有不同的方法,所以我有些失落,为此我深表歉意。
我的store.js看起来像这样
import rootReducer from "./reducers";
import thunk from "redux-thunk";
const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;
我在reducers文件夹的index.js中使用了CombineReducers,而auth:指向authReducer.js文件,这就是
const INIT_STATE = {
email: "",
password: "",
isLoggedIn: "false"
};
export default (state = INIT_STATE, action) => {
switch (action.type) {
case IS_LOGGED_IN_CHANGE:
console.log(action);
return {
isLoggedIn: action.value
};
default:
return state;
}
};
现在我的目标是要有一个将“ IsLoggedIn”初始状态更改为真实字符串而不是false的按钮,我进入了action文件夹,并制作了一个authActions.js,看起来像这样
import { IS_LOGGED_IN_CHANGE } from "../actions/types";
import store from "../store";
export const isLoggedInChange = value => {
return dispatch => {
dispatch({
type: IS_LOGGED_IN_CHANGE,
value
});
};
};
最后,我想向您展示我的组件页面,其中显示了所有这些内容,就像这样
import { connect } from "react-redux";
import styles from "./Landing.module.css";
import { isLoggedInChange } from "../../actions/authActions";
class Landing extends Component {
makeTrue = () => {
isLoggedInChange("true");
};
constructor(props) {
super(props);
this.state = {
email: "",
password: ""
};
}
render() {
return (
<div className={styles.background}>
<button onClick={this.makeTrue}>MAKE TRUE</button>
{this.props.isLoggedIn}
</div>
);
}
}
const mapStateToProps = state => ({
isLoggedIn: state.auth.isLoggedIn
});
const mapDispatchToProps = dispatch => ({
isLoggedInChange: value => dispatch(isLoggedInChange(value))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Landing);
你能告诉我是否丢了东西吗?为什么按钮不更改存储状态? TIA
答案 0 :(得分:1)
这里有两个问题。您是直接致电您的行动创建者,而不是props.isLoggedInChange
makeTrue = () => {
this.props.isLoggedInChange("true");
};
您需要在行动中传播旧状态
case IS_LOGGED_IN_CHANGE:
console.log(action);
return {
...state,
isLoggedIn: action.value
};
mapDispatchToProps
的意义不是像我一样可以立即使用该功能
是的,问题是mapDispatchToProps
将包装在dispatch
中的一个(或多个)函数注入到props
中。
import { actionCreator } from './actions
const mapDispatchToProps = dispatch =>({
actionCreator : () => dispatch(actionCreator)
})
现在您有两个actionCreator
,一个在作用域中全局可用(这是您的动作创建者),而props.actionCreator
是包装在dispatch
中的原始动作创建者。因此,当您从组件内部调用actionCreator()
时,不会抛出任何错误(因为在作用域中有一个名为actionCreator
的函数,但是您将调用错误的函数,所以找到了正确的函数)在props.actionCreator
。
我为什么需要传播状态?
reducer是一个纯函数,它接收state
和action
并返回新状态。当您刚返回
return {
isLoggedIn : true
}
您实际上是在覆盖原始状态(其中包含其他属性),因此首先您需要spread
保持原始状态以保持其结构完整性,然后覆盖您想要的属性
return{
...state,
isLoggedIn : !state.isLoggedIn
}
答案 1 :(得分:1)
Redux状态是不可变的,因此您需要返回状态的全新实例,并将reducer状态更改为以下状态。
export default (state = INIT_STATE, action) => {
switch (action.type) {
case IS_LOGGED_IN_CHANGE:
console.log(action);
return Object.assign({}, state, {
isLoggedIn: action.value
});
default:
return state;
}
};
关键区别在于
return Object.assign({}, state, {
isLoggedIn: action.value
});
Object.assign以我在这里使用的方式将状态对象组合成一个全新的对象。检查redux reducers中的不变性,我建议添加redux-immutable-state-invariant作为开发包,它可以检测何时直接修改状态并帮助指出此类错误
答案 2 :(得分:0)
使用isLoggedIn
的新值返回状态。像这样使用减速器:
case IS_LOGGED_IN_CHANGE:
console.log(action);
return {
...state,
isLoggedIn: action.value
};