0

I am trying to update a single element after filling its Modal form, but the state becomes empty, i.e rather than updating the element it deletes all elements.
I also asked another question and clarified what I want to do exactly, you can find it here https://stackoverflow.com/posts/69064392/edit


BTW, I am using Redux & react-flow-renderer libraries.

Reducer

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

const initialState = {
  elements: []
};

const flow = (state = initialState, action) => {
  switch (action.type) {
    case types.UPDATE_ELEMENT:
      return {
        ...state,
        elements: state.elements.map((e) => {
          if (e.id === action.payload.id) {
            e = {
              ...e,
              options: action.payload.options,
            };
          }
          return e;
        }),
      };
    default:
      return state;
  }
};

export default flow;

Action

import { UPDATE_ELEMENT } from './types';

export const updateElement = (data) => (dispatch) => {
  dispatch({
    type: UPDATE_ELEMENT,
    payload: data,
  });
};

Node modal

import React, { useState } from 'react';

import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { updateElement } from '../../../../redux/actions/flow';

const VPCNodeModal = (props, { updateElement }) => {

  const [formData, setFormData] = useState({
    instance: '',
  });

  // options
  const { instance } = formData;

  const onFormChange = (e) =>
    setFormData({ ...formData, [e.target.name]: e.target.value });

  const onSubmitForm = () => {
    const update = {
      id: selectedElement.id,
      options: formData,
    };

    updateElement(update);
  };

  return (
    <>
      <Modal {...props}>
          <form
            onSubmit={(e) => {
              e.preventDefault();
              onSubmitForm();
            }}
          >
            <label>
              <span> Instance name:</span>
              <input
                type='text'
                name='instance'
                value={instance}
                onChange={onFormChange}
              />
            </label>
            <button type='submit'>Submit</button>
          </form>
      </Modal>
    </>
  );
};

VPCNodeModal.propTypes = {
  updateElement: PropTypes.func.isRequired
};

export default connect(null, { updateElement })(VPCNodeModal);

9
  • You pass null instead of mapStateToProps function. Commented Sep 6, 2021 at 13:35
  • Yes I'm passing null because I don't need to access the state object I just need the action updateElement to dispatch it Commented Sep 6, 2021 at 16:31
  • Did you check the state with redux debugger? Commented Sep 6, 2021 at 17:07
  • Yes I'm using redux-devtools-extension Commented Sep 6, 2021 at 17:43
  • 1
    1. Reassign function parameter, as you do in map callback, is not a good style 2. Are you using two or more reducers for one item, or has your switch case statement just one action type for demo reasons? Commented Sep 6, 2021 at 18:38

1 Answer 1

1

You are mapping your elements array through a function that isn't returning anything when the id of the element doesn't match the action.payload.id.

Try this for your reducer:

const flow = (state = initialState, action) => {
switch (action.type) {
    case types.UPDATE_ELEMENT:
        return {
            ...state,
            elements: state.elements.map((e) => e.id === action.payload.id ? {...e, options: action.payload.options} : e),
        };
    default:
        return state;
    }
};
Sign up to request clarification or add additional context in comments.

2 Comments

It's still have the same behavior
The error was not in this code, but I used your approach to refactor mine. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.