Javascript 能不能“a”;减速机;在Redux中,是否默认返回初始状态和默认值?
我在学校学习Redux,因此我们使用测试来确保通过基准测试,以帮助我们理解构建模块 我已经完成了创建Javascript 能不能“a”;减速机;在Redux中,是否默认返回初始状态和默认值?,javascript,redux,Javascript,Redux,我在学校学习Redux,因此我们使用测试来确保通过基准测试,以帮助我们理解构建模块 我已经完成了创建Reducer函数的部分,我几乎完成了\o/,但是我无法通过一个测试 1) 默认情况下返回初始状态 在控制台下面吐出来的是 默认情况下,Reducer返回初始状态: AssertionError:应为未定义的对象 在上下文中。(测试/修订规范js:103:49) 我认为这是因为测试处理了一个人应该负责的一些问题,例如导入、创建动作类型等,但不是全部。也许我错过了考试没有提供的东西 无论如何,这是我
Reducer
函数的部分,我几乎完成了\o/
,但是我无法通过一个测试
1) 默认情况下返回初始状态
在控制台下面吐出来的是
默认情况下,Reducer返回初始状态:
AssertionError:应为未定义的对象
在上下文中。(测试/修订规范js:103:49)
我认为这是因为测试处理了一个人应该负责的一些问题,例如导入、创建动作类型等,但不是全部。也许我错过了考试没有提供的东西
无论如何,这是我的reducer文件:
import pet from "../components/PetPreview";
import { createStore } from "redux";
import { adoptPet, previewPet, addNewDog, addNewCat } from "./action-creators";
// ACTION TYPES
const PREVIEW_PET = "PREVIEW_PET";
const ADOPT_PET = "ADOPT_PET";
const ADD_NEW_DOG = "ADD_NEW_DOG";
const ADD_NEW_CAT = "ADD_NEW_CAT";
// INTITIAL STATE
const initialState = {
dogs: [
{
name: "Taylor",
imgUrl: "src/img/taylor.png"
},
{
name: "Reggie",
imgUrl: "src/img/reggie.png"
},
{
name: "Pandora",
imgUrl: "src/img/pandora.png"
}
],
cats: [
{
name: "Earl",
imgUrl: "src/img/earl.png"
},
{
name: "Winnie",
imgUrl: "src/img/winnie.png"
},
{
name: "Fellini",
imgUrl: "src/img/fellini.png"
}
]
// These dogs and cats are on our intial state,
// but there are a few more things we need!
};
export default function reducer(prevState = initialState, action) {
var newState = Object.assign({}, prevState)
console.log('initialState', typeof initialState)
switch (action.type) {
case PREVIEW_PET:
// console.log('newState', newState)
return Object.assign({}, prevState, {
petToPreview: action.pet
});
break
case ADOPT_PET:
return Object.assign({}, prevState, {
petToAdopt: action.pet
});
break
case ADD_NEW_DOG:
// console.log('action', action.dog)
// console.log('prevState.dogs', prevState.dogs)
newState.dogs = prevState.dogs.concat([action.dog])
return newState;
break
case ADD_NEW_CAT:
// console.log('action', action.dog)
// console.log('prevState.dogs', prevState.dogs)
newState.cats = prevState.cats.concat([action.cat])
return newState;
break;
default:
return prevState;
}
return initialState
}
正如您在开关
块后看到的,我返回初始状态
难道不是这样吗
下面是redux.spec.js
文件:
import { expect } from "chai";
import { createStore } from "redux";
// You will write these functions
import {
previewPet,
adoptPet,
addNewDog,
addNewCat
} from "../src/store/action-creators";
import reducer from "../src/store/reducer";
const DOGS = [
{
name: "Taylor",
imgUrl: "src/img/taylor.png"
},
{
name: "Reggie",
imgUrl: "src/img/reggie.png"
},
{
name: "Pandora",
imgUrl: "src/img/pandora.png"
}
];
const CATS = [
{
name: "Earl",
imgUrl: "src/img/earl.png"
},
{
name: "Winnie",
imgUrl: "src/img/winnie.png"
},
{
name: "Fellini",
imgUrl: "src/img/fellini.png"
}
];
function getRandomPet(pets) {
return pets[Math.floor(Math.random() * pets.length)];
}
describe("Action creators", () => {
describe("previewPet", () => {
it("returns properly formatted action", () => {
const pet = getRandomPet(DOGS);
expect(previewPet(pet)).to.be.deep.equal({
type: "PREVIEW_PET",
pet: pet
});
});
});
describe("adoptPet", () => {
it("returns properly formatted action", () => {
const pet = getRandomPet(DOGS);
expect(adoptPet(pet)).to.be.deep.equal({
type: "ADOPT_PET",
pet: pet
});
});
});
describe("addNewDog", () => {
it("returns properly formatted action", () => {
const pet = getRandomPet(DOGS);
expect(addNewDog(pet)).to.be.deep.equal({
type: "ADD_NEW_DOG",
dog: pet
});
});
});
describe("addNewCat", () => {
it("returns properly formatted action", () => {
const pet = getRandomPet(CATS);
expect(addNewCat(pet)).to.be.deep.equal({
type: "ADD_NEW_CAT",
cat: pet
});
});
});
}); // end Action creators
describe("Reducer", () => {
let store;
beforeEach("Create the store", () => {
// creates a store (for testing) using your (real) reducer
store = createStore(reducer);
});
it("returns the initial state by default", () => {
// In addition to dogs and cats, we need two more fields
expect(store.getState().petToPreview).to.be.an("object");
expect(store.getState().petToAdopt).to.be.an("object");
});
describe("reduces on PREVIEW_PET action", () => {
it("sets the action's pet as the petToPreview on state (without mutating the previous state)", () => {
const prevState = store.getState();
const pet = getRandomPet(DOGS);
const action = {
type: "PREVIEW_PET",
pet: pet
};
store.dispatch(action);
const newState = store.getState();
// ensures the state is updated properly - deep equality compares the values of two objects' key-value pairs
expect(store.getState().petToPreview).to.be.deep.equal(pet);
// ensures we didn't mutate anything - regular equality compares the location of the object in memory
expect(newState.petToPreview).to.not.be.equal(prevState.petToPreview);
});
});
describe("reduces on ADOPT_PET action", () => {
it("sets the action's pet as the petToAdopt on state (without mutating the previous state)", () => {
const prevState = store.getState();
const pet = getRandomPet(DOGS);
const action = {
type: "ADOPT_PET",
pet: pet
};
store.dispatch(action);
const newState = store.getState();
expect(newState.petToAdopt).to.be.deep.equal(pet);
expect(newState.petToAdopt).to.not.be.equal(prevState.petToAdopt);
});
});
describe("reduces on ADD_NEW_DOG action", () => {
it("adds the new dog to the dogs array (without mutating the previous state)", () => {
const prevState = store.getState();
const pet = getRandomPet(DOGS);
const action = {
type: "ADD_NEW_DOG",
dog: pet
};
store.dispatch(action);
const newState = store.getState();
expect(newState.dogs.length).to.be.equal(prevState.dogs.length + 1);
expect(newState.dogs[newState.dogs.length - 1]).to.be.deep.equal(pet);
expect(newState.dogs).to.not.be.equal(prevState.dogs);
});
});
describe("reduces on ADD_NEW_CAT action", () => {
it("adds the new cat to the cats array (without mutating the previous state)", () => {
const prevState = store.getState();
const pet = getRandomPet(CATS);
const action = {
type: "ADD_NEW_CAT",
cat: pet
};
store.dispatch(action);
const newState = store.getState();
expect(newState.cats.length).to.be.equal(prevState.cats.length + 1);
expect(newState.cats[newState.cats.length - 1]).to.be.deep.equal(pet);
expect(newState.cats).to.not.be.equal(prevState.cats);
});
});
describe("handles unrecognized actions", () => {
it("returns the previous state", () => {
const prevState = store.getState();
const action = {
type: "NOT_A_THING"
};
store.dispatch(action);
const newState = store.getState();
// these should be the same object in memory AND have equivalent key-value pairs
expect(prevState).to.be.an("object");
expect(newState).to.be.an("object");
expect(newState).to.be.equal(prevState);
expect(newState).to.be.deep.equal(prevState);
});
});
}); // end Reducer
提前谢谢 switch语句中的所有路径都会导致一个
返回
,这意味着倒数第二行的返回初始状态
是不可访问的。
另外,您的newState
只不过是prevState
的克隆,没有必要。
删除它,并为switchcase添加一个helper函数,再加上一些es6 spread love,您的代码就变得
const switchcase = cases => defaultValue => key =>
(key in cases ? cases[key] : defaultValue);
const reducer = (state = initialState, action) =>
switchcase({
[PREVIEW_PET]: { ...state, petToPreview: action.pet },
[ADOPT_PET]: { ...state, petToAdopt: action.pet },
[ADD_NEW_DOG]: { ...state, dogs: [...state.dogs, action.dog] },
[ADD_NEW_CAT]: { ...state, cats: [...state.cats, action.cat] },
})(state)(action.type);
所有的混乱都消失了,很明显问题在于,如果action.type==undefined
,代码返回initialState
对象。您的initialState
对象只包含dogs
和cats
属性,而您的测试预期会有petToPreview
和petToAdopt
属性
您可以在
初始状态中添加这些属性
,也可以根据需要的功能更改测试。默认情况下是否应该返回上一个状态?默认情况下,reducer不关心操作,只返回其当前状态,在您的示例中为prevState。在测试用例中,其中一个测试用例默认表示
it("returns the initial state by default", () => {
// In addition to dogs and cats, we need two more fields
expect(store.getState().petToPreview).to.be.an("object");
expect(store.getState().petToAdopt).to.be.an("object");
});
这意味着必须在初始阶段将petTpPreview和petToAdapt protery连接到商店。这可以通过将这两个对象添加到状态中来实现,如下所示
// INTITIAL STATE
const initialState = {
petToPreview:{},
petToAdopt: {},
dogs: [
{
name: "Taylor",
imgUrl: "src/img/taylor.png"
},
{
name: "Reggie",
imgUrl: "src/img/reggie.png"
},
{
name: "Pandora",
imgUrl: "src/img/pandora.png"
}
],
cats: [
{
name: "Earl",
imgUrl: "src/img/earl.png"
},
{
name: "Winnie",
imgUrl: "src/img/winnie.png"
},
{
name: "Fellini",
imgUrl: "src/img/fellini.png"
}
]
// These dogs and cats are on our intial state,
// but there are a few more things we need!
};
希望有帮助 嘿,我不能理解确切的问题,你想默认返回初始状态吗?如果是,发生了什么,你能解释一下吗further@mindaJalaj现在发生的事情似乎是最后一次没有通过的测试。本质上,默认情况下,
返回初始状态
未通过。我认为@jaihindhreddy很好地回答了这个问题,它有效吗?老实说,我没有尝试过。我读过了,有些结论是不正确的(尽管在我现在的代码中需要newState变量)。我想我宁愿有人帮我写代码,而不是重写代码。有一些伟大的洞察力,我很欣赏这只手,但似乎这是一个令人眼花缭乱的练习,而不是在教学中。就像没有太多的解释和教学,这是一个很好的回答问题的标志。此外,使用诸如“显而易见”和“杂乱无章”之类的词似乎有点过分,因为我说我确实对它投了“赞成票”。嘿,仅仅因为我不明白,并不意味着其他人可能不认为它是金子……那是我的朋友!真不敢相信这么简单!实际上它说的是,//这些狗和猫处于我们的初始状态,//但我们还需要一些东西代码>作为提示!另外,我认为这是一种心理上的转变,就像你刚才演示的那样,在React和Redux中按照正常的方式保存状态,而不是保存状态!非常感谢。不客气。希望你喜欢这个答案,一切都很清楚。真的!水晶!