15

I came across an issue today, consider following component:

export default class Input extends React.Component {
  someFunction() {
    console.log(this.props.value)
  }

  render () {
    const { type, value, required } = this.props
    return (
      <div className={cx('Input')}>
        <input type={type} value={value} required={required} />
      </div>
    )
  }
}

I am successfully destrucutring this.props and can use them within the render, however what if I need to use prop values outside of it i.e. inside someFunction() I am not sure to what would the consequences be if I move out constant { ... } and include right after export default class Input extends React.Component { line. Will this still be valid?

Mulan
  • 129,518
  • 31
  • 228
  • 259
Ilja
  • 44,142
  • 92
  • 275
  • 498
  • If you do that, `this.props` will be undefined because it will execute before the item is rendered. Why do you want to do that? – Ruan Mendes Jun 29 '16 at 15:46
  • @JuanMendes for consistency, so I don't need to write this.props outside render as well – Ilja Jun 29 '16 at 15:46
  • 3
    I don't see the point of what you are doing, trying to avoid duplicating `const { type, value, required } = this.props`? Bad idea I would say, it's likely that you will need different values in different methods. If you write a real example with duplication you would like to avoid, then you have yourself a better question. It's unclear why you need this, it looks like you're over-engineering it – Ruan Mendes Jun 29 '16 at 15:52
  • "*... successfully decoupling `this.props` ...*" - do you mean *destructuring* ? – Mulan Jun 29 '16 at 16:12
  • @naomik updated, that was what I meant – Ilja Jun 29 '16 at 16:14

3 Answers3

11

If you move it outside they would be null , because at that time constructor would not have got called.

It is a recommender approach to keep it in render or function because your parent component can change state which will cause your child to get rerendered ,So you need fresh props for every render .

Piyush.kapoor
  • 6,715
  • 1
  • 21
  • 21
7

Correctly destructuring this.props for the whole component

Well you can't do that. Destructuring can only assign local variables so you'd need to destructure props in each function. Otherwise there's nothing wrong with having to write this.props.value. Use destructuring when it helps readability, not just because you don't feel like typing this.props.

I would write your code like this

// import cx from whatever

const someFunction = value=> console.log(value)

export const Input = ({type, value, required}) => (
  someFunction(value),
  <div className={cx('Input')}>
    <input type={type} value={value} required={required} />
  </div>
)
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • "Destructuring can only assign local variables...." I think this is at least misleading. [You _can_ destructure props into member variables in a constructor](https://stackoverflow.com/a/38127538/99717). But, I would agree that it's rarely (maybe never) a good idea. – Hawkeye Parker Apr 19 '22 at 22:48
  • Thanks for the comment, Hawkeye. That's the most offensive bit of JavaScript I've seen in a long time :D – Mulan Apr 19 '22 at 22:53
3

Maybe consider updating it to a functional component.

function someFunction(props) {
  console.log(props.value)
}

function Input(props) {
  const { type, value, required } = props;

  someFunction(props); // logs props.value

  return (
    <div className={cx('Input')}>
      <input type={type} value={value} required={required} />
    </div>
  )
}

export default Input;
RickTakes
  • 1,197
  • 1
  • 9
  • 14
  • I think the OP wants the variables `type, value, required` to already be defined in other functions? It's hard to grasp what the OP is really looking for... – Ruan Mendes Jun 29 '16 at 15:53
  • Ah I see. I think they will have to be passed around then. A redux solution would handle that pretty nicely. – RickTakes Jun 29 '16 at 15:57