1

Expected behaviour of this component is like this: I press it, selectedOpacity() function is called, state is updated so it now renders with opacity=1.

But for some reason, after calling this.setState, it is not being re-rendered. I have to click this component again to make it re-render and apply changes of opacity from state.

export default class Category extends Component {

state = {
  opacity: 0.5
}

selectedOpacity() {
  // some stuff
  this.setState({opacity: 1})
}

render() {
 return(
  <TouchableOpacity style={[styles.container, {opacity: this.state.opacity}]} onPress={() => {
    this.selectedOpacity();
  }}>
  </TouchableOpacity>
 )
}
TheRuthlessHacker
  • 105
  • 1
  • 2
  • 10
  • missing `constructor()` – xadm May 08 '19 at 23:20
  • 1
    Possible duplicate of [Dynamic Opacity not changing when component rerenders in react native](https://stackoverflow.com/questions/47979866/dynamic-opacity-not-changing-when-component-rerenders-in-react-native) – sinan May 08 '19 at 23:41
  • So it appears that using TouchableOpacity there is bugged in this scenario, any ideas though to avoid this bugg and still use TouchableOpacity? – TheRuthlessHacker May 08 '19 at 23:59

3 Answers3

0

Change selectedOpacity to arrow function:

selectedOpacity = () => {
  this.setState({opacity: 1})
}

Then:

onPress={this.selectedOpacity}

Edit: The react documentation says its experimental and the syntax is called public class field syntax.

PrivateOmega
  • 2,509
  • 1
  • 17
  • 27
carter108
  • 71
  • 3
  • this would be undefined in arrow functions AFAIK if not bound. – PrivateOmega May 09 '19 at 04:36
  • @KiranMathewMohan Have you ever tried that before? I think you're totally wrong – carter108 May 09 '19 at 05:02
  • Yes ofcourse. "An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords." Ref: [mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) – PrivateOmega May 09 '19 at 05:06
  • @KiranMathewMohan Seriously? A lot of people around the world are using arrow function instead of binding(ES6). Please read this article https://reactjs.org/docs/handling-events.html – carter108 May 09 '19 at 05:27
  • Thanks for correcting me. I just read that the syntax you posted should work. But it says its experimental. Its called [public class field syntax](https://babeljs.io/docs/plugins/transform-class-properties/). Could you please edit the answer and include this information for posterity and to remove the downvote. – PrivateOmega May 09 '19 at 05:39
  • Not anymore. Like I said, people are almost using it instead of binding – carter108 May 09 '19 at 05:42
  • AFAIK An experimental feature is one where the design is not finalized. The feature is available for users to test and provide feedback. – PrivateOmega May 09 '19 at 05:46
  • 1
    You can google it. I don't want to argue with you. We can end of discussion here. – carter108 May 09 '19 at 05:58
  • Sure man. It's just a constructive talk, that's all. Don't take offense. – PrivateOmega May 09 '19 at 05:59
0

I think what you are missing is binding of selectedOpacity(), else this would be undefined in it AFAIK.

Also better move the assignment of state to a constructor().

constructor(props) {
    super(props);
    this.state = {};
    this.selectedOpacity = this.selectedOpacity.bind(this);
}

Also change to the following because creating an arrow function inside render affects performance.

onPress={this.selectedOpacity}
PrivateOmega
  • 2,509
  • 1
  • 17
  • 27
-2

Try change onpress to onPress={() => this.selectedOpacity()}

Leighton
  • 1,128
  • 11
  • 14