1

Design explained


I have a React class with an arrow function that gets called from within child classes (modules). It's simply called saveData and its purpose is to save an input value specific to each module to be saved to state. So well, my default state has default props (static defaultProps):

state = {
  a : this.props.initialA,
  b : this.props.initialB,
  c : ...
}

And said saveData function is a fat arrow function that's supposed to push the input value from the child class to a specific state property in the parent:

saveData = (val) => this.setState( {a : val} )

Each child class gets the saveData function passed with JSX and has its own input. When a button is clicked I call the function with the value as parameter:

/* A child class */

pushData = (e) => {
  e.preventDefault()
  const val = this.refs.a.value
  this.props.saveData(val)
}

render() {
  return(
    <input id='a' ref='a' ... />
    <button onClick={this.pushData} ... />
  )
}



This is all fine! Now for my concern

As you can see the state property a is hard coded in the above examples. This is not what I want. I would want to have another parameter set the state property which in my head could be as simple as:

/* In parent class */

saveData = (prop, val) => this.setState( {prop : val} )


/* In child class */

pushData = (e) => {
  ...
  const val  = this.refs.a.value,
        prop = a;
  this.props.saveData(prop, val)
}

Now here are the problems I face with this approach:

  • Did I understand right that arrow functions don't accept parameters? Because I totally do use (e) in pushData and even (val) in saveData has worked for me before.
  • The crucial point: Whatever way I put it, the property in this.setState({prop:val}) won't get assigned. It will just add a new property called prop even if prop is a variable, a parameter, or a rest parameter with a totally different content.


Is there a way to have ...setState({prop... be assigned by the child class?

(Or am I just being overly complicated? Am I not thinking React? I sometimes feel like thinking in React is like thinking $con"!"\˜*.ht"&&su20%+o?else{((())...())}of)

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Marian
  • 1,352
  • 4
  • 15
  • 28
  • Possible duplicate of [Using a variable for a key in a JavaScript object literal](http://stackoverflow.com/questions/2274242/using-a-variable-for-a-key-in-a-javascript-object-literal) – Felix Kling Dec 13 '15 at 06:15
  • @FelixKling I would want to mark this accordingly, yet I feel like the question is definetly not a duplicate. People might find this problem of mine looking for ReactJS and the setState function cause they don't even know what they're doing wrong (like me). Apparently the solution is mentioned there, just like it is here. Is the same solution to a different question still a duplicate? Please clarify and I'll mark accordingly. – Marian Dec 13 '15 at 17:25

1 Answers1

1

Arrow functions are nothing but syntactic sugar for

()=>{} is equivalent to function(){}.bind(this)

So, they behave exactly similar to any other function, except that the scope is lexically bound. It does take params. If saveData is not working in the way you want it to, you are probably invoking the function with wrong values.

And,when you do this

saveData = (prop, val) => this.setState( {prop:val} )

javascript does not evaluate prop as a variable. Here 'prop' is interpreted as a string.

Instead, try this in ES5

var temp = {};
temp[prop] = val;
saveData = (prop, val) => this.setState( temp )

or this, in ES6,

saveData = (prop, val) => this.setState({[prop]:val})

[] allows you to evaluate a variable enclosed within it.

Bhargav Ponnapalli
  • 9,224
  • 7
  • 36
  • 45
  • You sir, released my headache I've had for hours within a few minutes...Thank you very much! Would you mind explaining a bit futher why JavaScript won't interpret `prop` but `val` and why I have to enclose the `prop` param in square brackets? Not something I'd normally do, but this was the whole solution to this. – Marian Dec 13 '15 at 05:08
  • 1
    That's how Javascript should work right? If you want to do {title:'Sometititle'}, interpreting 'title' as a variable doesn't make sense, it is intended to be a string. However, there are cases where you need to create dynamic props and, which is why, our forefathers have blessed us with '[ ]' in Javascript. Glad I could help Marian. – Bhargav Ponnapalli Dec 13 '15 at 05:25
  • Makes me feel like I started with JS yesterday hahaha...Thank you for the explanation! – Marian Dec 13 '15 at 05:45