javascript - Redux:根据 Actions 改变 Reducer 中初始状态的不同部分
问题描述
我有以下减速器:
const initialState = {}
const dishReducer = (state = initialState, action) => {
switch (action.type) {
case 'LOAD_DISHES':
return (action.dishes)
case 'LOAD_DISHES_ERROR':
console.log("load dishes error")
return state
case 'LOAD_DISHES_SUCCESS':
console.log("load dishes success")
return state
default:
return state;
}
};
export default dishReducer;
以及以下操作:
import {database} from '../../config/fbConfig'
export const startLoadingDishes = (dishes) => {
return (dispatch) =>{
return database.ref('products-dishes').once('value').then((snapshot) => {
let dishes = {}
snapshot.forEach((childSnapshot) => {
let parentkey = childSnapshot.key
let dishArray = [];
childSnapshot.forEach((dish) =>{
dishArray.push(dish.val())
});
dishes[childSnapshot.key] = dishArray;
})
dispatch(loadDishes(dishes))
}).then(() => {
dispatch({ type: 'LOAD_DISHES_SUCCESS' });
}).catch(err => {
dispatch({ type: 'LOAD_DISHES_ERROR' }, err);
});
}
}
export const loadDishes = (dishes) => {
return {
type: 'LOAD_DISHES',
dishes
}
}
在某个组件的 componentDidLoad() 中调用了“startLoadingDishes”操作。但是,我想更改我的 discReducer 的初始状态,以便它包含附加信息,如下所示:
const initialState = {
value : {},
loaded: false,
loading: false,
error: false
}
所以现在由 reducer 返回的 'action.dishes' [在 'LOAD_DISHES' 情况下] 应该放在状态的 'value' 部分,而不是整个状态。此外,如果菜肴之前已加载,则状态的“已加载”部分应设置为 true,依此类推。我知道这相当简单,但由于我是 React+Redux 的新手,我不知道如何正确更改 Action/Reducer 代码(同时保持状态不变性)。任何帮助表示赞赏。
解决方案
我最初问了这个问题,这是我解决它的方法(虽然不确定这是否是“最好的”方法):
新的减速器文件:
const initialState = {
value : {},
loaded: false,
loading: false,
error: false
}
const dishReducer = (state = initialState, action) => {
switch (action.type) {
case 'LOAD_DISHES':
return {
value: action.dishes,
loading: !state.loading,
loaded: false, //this might need to be set to true
error: false
}
case 'LOAD_DISHES_ERROR':
console.log("load dishes error")
return {
...state, //or: state.value, as the other parts of state are being overwritten below
loaded: false,
loading: false,
error: true
}
case 'LOAD_DISHES_SUCCESS':
console.log("load dishes success")
return {
...state, //better: state.value
loaded: true,
loading: false,
error: false
}
default:
return state;
}
};
export default dishReducer;
动作文件没有变化。
现在,在“主要”组件中,我最初是这样访问状态的:
class Main extends Component {
componentDidMount() {
this.props.startLoadingDishes();
}
render() {
return (
//some code
)
}
}
const mapStateToProps = (state) => {
return {
dishes: state.dishes //to access dishes: dishes.value
}
}
export default connect(mapStateToProps, actions)(Main)
主要组件代码也保持不变,不同之处在于现在我使用 'dishes.value' 而不仅仅是 'dishes' 从状态中访问菜肴的值(并且为加载的 disces.loaded 等等)。现在 componentDidMount 内部的动作调用者如下:
componentDidMount() {
if(!this.props.dishes.loaded){
this.props.startLoadingDishes();
console.log("loading dishes from database")
}
}
推荐阅读
- regex - 使用正则表达式的 Angular 响应式表单中的模式验证器
- c# - 从控制台应用程序引用时,静态文件不适用于 AspNetCore Web 应用程序
- c# - 如何使用 Chart.js 中的 ChartBar 和 Bootstrap 4 中的警报对齐元素?
- apache-spark - spark 3.0 中的 glob
- java - 如何关闭枚举的反序列化
- reactjs - 在功能组件中反应承诺
- sql-server - Microsoft SQL Server 2016 - 将 varchar 转换为带有 $ 符号和 2 位小数的货币
- sql - 按日期建立日期参数:小时而不是日期
- class - 如何从飞镖颤振中的单个泛型类返回多种类类型?
- postgresql - 将 postgresql 从版本 11 升级到 12 会导致“您的安装引用了丢失的可加载库”