我正在创建一组团队按钮,它们可以在单击按钮时进行上/下级升级。卡根据状态(一个数组)进行渲染。我不确定动作创建者和减速器中的代码应该是什么。
有效方法:
使用state.map()和mapStateToProps()
LEVEL_UP操作会在点击时调度,因为我在redux开发工具中可以看到它
什么不起作用:
**TeambuilderCards.js**
import React from "react";
import { connect } from "react-redux";
import TeamBuilderCard from "./TeamBuilderCard.js";
const TeamBuilderCards = ({ teamMembers }) => {
return (
<div className="ui centered cards">
{teamMembers.map(teamMember => (
<TeamBuilderCard
key={teamMember.id}
name={teamMember.name}
xp={teamMember.xp}
/>
))}
</div>
);
};
const mapStateToProps = state => {
return {
teamMembers: state
};
};
export default connect(mapStateToProps)(TeamBuilderCards);
**Teambuildercard.js**
import React from "react";
import { connect } from "react-redux";
import { levelUp, levelDown } from "../actions";
const roundUp = num => Math.ceil(num / 100) * 100;
const TeamBuilderCard = (props, dispatch) => (
<div className="ui card">
<div className="content">
<div className="header">{props.name}</div>
<div className="description">
<h3>Current Level: {props.xp.toString().slice(0, 1)}</h3>
<p>XP is currently {props.xp}</p>
<p> {roundUp(props.xp) - props.xp} xp points to to next level</p>
</div>
<div className="meta">
Increase or decrease {props.name}'s level with the buttons below
</div>
</div>
<div className="extra content">
<div className="ui two buttons">
<div className="ui basic green button" onClick={props.levelUp}>
Level up
</div>
<div className="ui basic pink button" onClick={props.levelDown}>
Level down
</div>
</div>
</div>
</div>
);
const mapDispatchToProps = { levelUp, levelDown };
export default connect(
null,
mapDispatchToProps
)(TeamBuilderCard);
**actions.js**
export const LEVEL_UP = "LEVEL_UP";
export const LEVEL_DOWN = "LEVEL_DOWN";
export function levelUp() {
return { type: LEVEL_UP };
}
export function levelDown() {
return { type: LEVEL_DOWN };
}
**reducers/index.js**
import { LEVEL_UP, LEVEL_DOWN } from "../actions";
import preloadedState from "../preloadedState"; *//preloadedState is and array and I want to modify state[i].xp*
const initialState = preloadedState;
export default function reducer(state = initialState, action) {
switch (action.type) {
case LEVEL_UP:
return state; *//want to add 100 XP*
case LEVEL_DOWN:
return state; *//want to subtract 100 XP*
default:
return state;
}
}
*preLoadedState.js* //Just the first 3 objects in the array
const preloadedState = [
{
id: "0",
name: "Pete",
xp: 153
},
{
id: "1",
name: "Jane",
xp: 121
},
{
id: "2",
name: "Jim",
xp: 188
}
];
export default preloadedState;
答案 0 :(得分:0)
导入并使用ladash映射循环遍历对象数组
减速器:
import map from 'lodash/map'
case LEVEL_UP:
let nextstate = map(preloadedState,(eachobject,index)=>{
let xp = eachobject.xp
eachobject.xp = xp + 100;
})
return nextstate;
答案 1 :(得分:0)
我认为最好的方法是在减速器上添加数学-
export const reducer = (state = preloadedState, action) => {
let newState = [...state] // now we can manipulate newState
switch (action.type) {
case 'LEVEL_UP':
newState[action.index].xp = state[action.index].xp + 100
return newState
case 'LEVEL_DOWN':
newState[action.index].xp = state[action.index].xp - 100
return newState
case 'ERROR':
console.log('has been error, ', action.err)
return state
default:
return state
}
}
请注意,我正在使用被调用用户数组中的索引来从正确的用户添加/减少XP。
/create one action for example
export const levelUp = index => {
return (dispatch, getState) => {
try {
dispatch({
type: 'LEVEL_UP',
index
})
} catch (err) {
dispatch({
type: 'ERROR',
err
})
}
}
}
我们要做的最后一件事是发送索引/无论您要从前端更改什么协议
<div className="ui basic green button" onClick={()=>props.levelUp(index)}> //you should define the index here
Level up
</div>
答案 2 :(得分:0)
实际上,我接受的上一个答案在控制台中返回了一些有关更改状态的错误。还有关于不可序列化数据的警告。可以通过忽略react-starter-kit的configureStore()中的检查来解决。
但是,这现在可以按计划进行,并且在控制台中没有任何错误,但是仍然要非常感谢,因为所有hagai harari的建议都可以解决问题。
import preloadedState from "../preloadedState";
export const reducer = (state = preloadedState, action) => {
switch (action.type) {
case "LEVEL_UP":
return state.map((xpUp, index) => {
if (index === action.index) {
return Object.assign({}, xpUp, {
xp: state[action.index].xp + 100
});
}
return xpUp;
});
case "LEVEL_DOWN":
return state.map((xpDown, index) => {
if (index === action.index) {
return Object.assign({}, xpDown, {
xp: state[action.index].xp - 100
});
}
return xpDown;
});
case "ERROR":
console.log("There has been an error, ", action.err);
return state;
default:
return state;
}
};