0

I want to edit one element from an array with react and redux.

My problem is I set once the state of array which I map. And in this map I try to change this element with reducer.

Is it possible?? I try to use Object.assing() to avoid mutate the state, BUT I must mutate the state. Isn`t it true?

Below the reducer:

import * as actionTypes from '../actions';

const iniState = {
  components: []
};
const rootReducer = (state = iniState, action) => {
  switch (action.type) {
    case actionTypes.ADD_COMPONENT:
      const newComponent = {
        id: Math.random(),
        co: action.data.compToReducer
      }
      return {
        ...state,
        components: state.components.concat(newComponent)
      };
    case actionTypes.DELETE_COMPONENT:
      return {
        ...state,
        components: state.components.filter(component=> component.id !== action.index)
      }
    case actionTypes.EDIT_COMPONENT:
      return
        Object.assing({}, state, {co: state.co = action.data.componentToReducer})

  }

  return state;
}

export default rootReducer;

And the container:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import FoodComponent from '../../components/FoodComponent/FoodComponent';
import AddComponent from '../../components/Buttons/AddComponent';
import * as actionTypes from '../../store/actions';
import classes from './FoodComponents.scss';

class FoodComponents extends Component {

  render() {
    return (
      <div>
        <AddComponent
          text="Add component"
          click={this.props.onAddComponent}
        />
        <ul>
          {
            this.props.compons.map(component=>(
          <li key={component.id}
          >
            <p className={classes.Component}>{component.co}</p>
            <input
              type="text"

              />
            <button
              onClick={this.props.onEditComponent}>
              Edit Component
            </button>
            <button
            onClick={()=>this.props.onDeleteComponent(component.id)}>
              Delete component
            </button>
          </li>
            ))
          }

          </ul>
      </div>
    )
  }
}

const mapStateToProps = state => {
  return {
    compons: state.components
  }
}
const mapDispatchToProps = dispatch => {
  return {
    onAddComponent: (component) => dispatch({type: actionTypes.ADD_COMPONENT, data: {compToReducer: component}}),
    onDeleteComponent: (id) => dispatch({type: actionTypes.DELETE_COMPONENT, index: id }),
    onEditComponent: (component, id) => dispatch({type: actionTypes.EDIT_COMPONENT, data:{componentToReducer: component, index: id}})
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(FoodComponents);
Joshua
  • 3,055
  • 3
  • 22
  • 37
Michał
  • 101
  • 10
  • 1
    Possible duplicate of [How to update single value inside specific array item in redux](https://stackoverflow.com/questions/35628774/how-to-update-single-value-inside-specific-array-item-in-redux) – Roy Wang May 11 '18 at 06:47
  • Yes it is! But my problem is to bind elements index with if statement in reducer. I use .map() and it works only with hardcoded integer, i === action.data.index for this example doesnt work. – Michał May 13 '18 at 06:09

1 Answers1

0
onEditComponent: (component, id) => dispatch({type: actionTypes.EDIT_COMPONENT, data:{componentToReducer: component, index: id}})

<button onClick={this.props.onEditComponent}>
  Edit Component
</button>

This won't work as you try to pass SyntheticEvent to the reducer. Synthetic events get nullified after callback executes.

Tomasz Mularczyk
  • 34,501
  • 19
  • 112
  • 166
  • I am stuck with it. Maybe there is a SyntheticEvent there but this is not the real problem here. The problem is how to pass changed/replaced state from reducer to container. – Michał May 11 '18 at 07:40