1

I am trying to copy the object I have in a component up to a property. I am able to get it to work like this:

 onSubmit: values => {

      data.label = values.label;
      data.userName = values.userName;
      data.recipientUserName = values.recipientUserName
      data.vanityURL = values.vanityURL;
      data.dollarAmount = values.dollarAmount;
      data.textData = values.textData;

I'm new to javascript but this feels very ugly. Is there a way I can do a direct shallow copy without iterating through every field?

The data object is created is passed in at the top as:

export default memo(({ id, data, isConnectable,setElements, removeElements}) => {

  const [show, setShow] = useState(false);
  const handleClose = (e) => {setShow(false)};
  const handleShow = () => setShow(true);

  
  const formik = useFormik({
    initialValues: {
      label: data.label,
      userName: '',
      recipientUserName: '',
      vanityURL: '',
      dollarAmount: '',
      textData: ''
    },
    onSubmit: values => {

      data.label = values.label;
      data.userName = values.userName;
      data.recipientUserName = values.recipientUserName
      data.vanityURL = values.vanityURL;
      data.dollarAmount = values.dollarAmount;
      data.textData = values.textData;
    },
    onReset: (values, { resetForm }) => resetForm(),
  });

return ( ....

The onSubmit is part of a Formik form.

user1357015
  • 11,168
  • 22
  • 66
  • 111

2 Answers2

1

In order to perform shallow copy, you can follow one of these methods.

  1. Use the spread (...) syntax
  2. Use the Object.assign() method
  3. Use the JSON.stringify() and JSON.parse() methods

Example 1

data = {...values}

Example 2

data = Object.assign({}, values)

Example 3

data = JSON.parse(JSON.stringify(values));
Eduard
  • 1,319
  • 6
  • 12
  • This doesn't work. Data is assigned as part of a handler in a Formik class and passed in as a prop. I've made this explicit now in the question. – user1357015 Jan 08 '22 at 06:20
  • It would be better to pass from the parent component a function that will accept the argument of new values, and mutate the `data` variable inside the parent not inside the child. – Eduard Jan 08 '22 at 06:25
  • Why? If I know specifically that the child is mutating that component? – user1357015 Jan 08 '22 at 06:26
  • Because there must be a single source of truth, otherwise if your parent rerenders, it will pass an old version of data to the child which will clear out the mutations performed inside your child. – Eduard Jan 08 '22 at 06:27
  • 1
    So generally data should be mutated at the same level, where it has been created OR you should create a local state out of its props and mutate local state. – Eduard Jan 08 '22 at 06:29
  • But if it's a shallow copy won't they both pointing to the same memory at that point? – user1357015 Jan 08 '22 at 06:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/240852/discussion-between-user1357015-and-eduard-hovhannisyan). – user1357015 Jan 08 '22 at 06:30
  • 1
    Very good point my friend, but javascript is ONLY `pass by value` not `by reference` – Eduard Jan 08 '22 at 06:31
0

You can do

const data = {...value}
Vishnu Sajeev
  • 941
  • 5
  • 11
  • do I need to do the const? it's passed as a prop? – user1357015 Jan 08 '22 at 06:17
  • Usually, props should not be mutated inside child components, unless you know the cost of it. – Eduard Jan 08 '22 at 06:19
  • In react props are not supposed to be mutated like what you are doing, data should always flow unidirectionally in react. Take a look at this thread https://stackoverflow.com/questions/47471131/why-are-react-props-immutable – Vishnu Sajeev Jan 08 '22 at 06:31
  • If you intend to pass the values to its parent component, you need to pass it using a function, which is passed as a props to this component. – Vishnu Sajeev Jan 08 '22 at 06:34
  • 3
    While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please [include an explanation for your code](//meta.stackexchange.com/q/114762/269535), as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Luca Kiebel Jan 08 '22 at 10:49