1

I have a function that getting val as a parameter and I want to set this.props.val as default value.

My current function:

foo(val = this.props.val) {
    console.log(val);
  }

I'm getting the follow lint error:

Must use destructuring props assignment (react/destructuring-assignment)

Is it possible to use props as a default value in a different way that will stand in the react/destructuring-assignment rule?

Maybe there is some trick similar to the following?

foo({ val } = this.props) {
    console.log(val);
  }

In the example above:

foo(5);// val = undefined
foo({val:5});// val = 5
foo();//val = this.props.val

Expected result

foo(5);// val = 5
foo({val:5});// val = {val:5}
foo();//val = this.props.val

[ I can use

foo(val) {
    const { val: valProps } = this.props;
    const newVal = val || valProps;
    console.log(newVal);
  }

but I'm trying to find a cleaner way]

yohaiz
  • 874
  • 6
  • 11

2 Answers2

0

It looks like you are trying to mix the type of the argument which function receives (sending integer or object) which is not the usual way to define function's parameters. I don't think you can handle such case in function's signature directly, but you could do something like this:

this.props = {x: 1, y: 2, val: 3}

const foo = ({ val = 'MY_DEFAULT_VALUE' } = this.props) => {
  console.log(val);
}

foo(5);  // val = MY_DEFAULT_VALUE
foo({ val: 5 });  // val = 5
foo();  //val = this.props.val

Alternatively, if you really have to support both types as an argument (integers and objects), you should handle the argument you received within the function itself, something similar to:

this.props = {x: 1, y: 2, val: 3}

const foo = (arg = this.props) => {
  if (arg.val) {  // Check if `arg` has a `val` property (meaning that `arg` is an object)
    console.log(arg.val);
  } else {  // `arg` is not an object with `val` property, assumed we got integer or empty param
    console.log(arg);
  }

  // Or even shorter:
  newVal = arg.val || arg;
  console.log(newVal);
}

foo(5);  // val = 5
foo({ val: 5 });  // val = 5
foo();  //val = 3 (from `this.props.val`)
errata
  • 5,695
  • 10
  • 54
  • 99
  • I added `expected result` to the question – yohaiz Jul 05 '20 at 15:14
  • @yohaiz I see, but foo({5}); is not a proper object, I assume you meant foo({val: 5});? Updated my answer with additional explanations... – errata Jul 05 '20 at 15:29
  • you right - I updated the question. The second approach is interesting but in case of `foo({ val: 5 }); // val = 5` I will expect `//val = { val: 5 }` – yohaiz Jul 05 '20 at 15:37
  • @yohaiz Does it make sense that if you send an object (`foo({val:5})`), you expect the whole object back (instead of just `val`) but if you omit the parameter (`foo()`) you need the value itself (`this.props.val` instead of `this.props` object)? – errata Jul 05 '20 at 17:35
  • I want it to behave like a regular default value. If the function got param -> use it (no mather if it an object or primitive), otherwise, set val as `this.props.val` – yohaiz Jul 06 '20 at 08:17
0

You are getting a lint error which isn't exactly an error since it isn't related to runtime but is just an opinionated best practice relating to code style. Your code seems fine with respect to javascript. What you can do is, ignore the rule for this specific line by putting this comment above your function, // eslint-disable-line react/destructuring-assignment or disable this rule entirely in your eslint config which totally depends on your code style.

  • tnx, I know that I can disable the rule... but I'm trying to fine a way that will stand in the react/destructuring-assignment rule – yohaiz Jul 05 '20 at 15:00