如何编写减速器/动作创建者组合以在单击按钮时更新状态?

我正在创建一组团队按钮,它们可以在单击按钮时进行上/下级升级。卡根据状态(一个数组)进行渲染。我不确定动作创建者和减速器中的代码应该是什么。

有效方法:

  1. 使用state.map()和mapstatetoProps()

  2. 用状态中的正确数据正确渲染卡片
  3. LEVEL_UP操作会在点击时调度,因为我在redux开发工具中可以看到它

什么不起作用:

  1. 该动作实际上还没有做任何事情
  2. 我尝试过的所有事情都导致未定义,因此我无法在reducer中访问正确的数据
**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;
dongxingchao 回答:如何编写减速器/动作创建者组合以在单击按钮时更新状态?

导入并使用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;
,

我认为最好的方法是在减速器上添加数学-


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>
,

实际上,我接受的上一个答案在控制台中返回了一些有关更改状态的错误。还有关于不可序列化数据的警告。可以通过忽略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,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;
  }
};
本文链接:https://www.f2er.com/3154561.html

大家都在问