【问题标题】:React Native TouchableOpacity not updating stylesReact Native TouchableOpacity 不更新样式
【发布时间】:2018-02-05 19:21:29
【问题描述】:

TouchableOpacity 组件有一个奇怪的问题。我有一个 MainButton 组件,它需要 2 个道具,itemdisabled。基于 disabled 道具,我希望我的 MainButton 组件应用不同的样式。问题是当TouchableOpacity 组件重新渲染时,它不会刷新样式。重新渲染时正确设置了道具 disabled

奇怪的是,如果我将其更改为 TouchableHeighlight,它会按预期工作。

有人知道为什么吗?这是 TouchableOpacity 中的错误吗?

import React, { Component } from 'react'
import UI from '../styles/ui'

import {
  Text,
  TouchableOpacity
} from 'react-native'

const ui = new UI()
const styles = ui.styles

class MainButton extends Component {
  constructor (props) {
    super(props)
    this.state = {
      disabled : props.disabled,
      item: props.item
    }
  }

  componentWillReceiveProps(props) {
    this.setState({disabled:props.disabled})
  }

  render() {
    var normalStyles = [styles.mainButton,styles.widthEighty]
    var disabledStyle = [styles.mainButton,styles.widthEighty,styles.lowOpacity]
    var correctStyles = this.state.disabled ? disabledStyle : normalStyles
    console.log(this.state.disabled,'this.state.disabled ? ');
    return (
      <TouchableOpacity disabled={this.state.disabled} style={correctStyles} accessibilityLabel={this.state.item.name} onPress={this.state.item.onPress.bind(this)}>
        <Text style={styles.mediumLabel}>{this.state.item.name}</Text>
      </TouchableOpacity>
    );
  }
}

export { MainButton as default }

【问题讨论】:

  • 你有没有弄明白这件事?我想知道它是否与 TouchableOpacity wrapping its children in an Animated.View 有关?动画没有及时完成还是什么?文档没有提到 TouchableHighlight 进行了类似的包装,但没有深入研究源代码进行检查!无论哪种方式,感谢 TouchableHighlight 提示!
  • 我遇到了同样的问题,感谢您提供的高亮提示
  • 您找到解决方案了吗?

标签: react-native touchableopacity touchablehighlight


【解决方案1】:

如果您使用 opacity 样式(由 TouchableOpacity 使用),您应该为 TouchableOpacity 的子项(例如视图)设置此样式,如下所示:

<TouchableOpacity
  disabled={disabled}
  accessibilityLabel={name}
  onPress={onPress}
>
  <View style={disabled ? disabledStyle : normalStyle}>
    <Text style={styles.mediumLabel}>{name}</Text>
  </View>
</TouchableOpacity>

【讨论】:

    【解决方案2】:

    我想出的解决方法是使用

    setOpacityTo(value) 以更新画布。

    我这样做了componentDidUpdate(),因为只要在组件中应用了新样式,就会调用这个生命周期方法。所以我给&lt;TouchableOpacity/&gt; 组件一个ref 并在它的样式发生变化时更新它。

    示例:

    import React, { Component } from 'react'
    import UI from '../styles/ui'
    
    import {
      Text,
      TouchableOpacity
    } from 'react-native'
    
    const ui = new UI()
    const styles = ui.styles
    
    class MainButton extends Component {
      constructor (props) {
        super(props)
        this.state = {
          disabled : props.disabled,
          item: props.item
        }
      }
    
      componentWillReceiveProps(props) {
        this.setState({disabled:props.disabled})
      }
    
      componentDidUpdate() {
        this.refs['touchable'].setOpacityTo(1.0);
      }
    
      render() {
        var normalStyles = [styles.mainButton,styles.widthEighty]
        var disabledStyle = [styles.mainButton,styles.widthEighty,styles.lowOpacity]
        var correctStyles = this.state.disabled ? disabledStyle : normalStyles
        console.log(this.state.disabled,'this.state.disabled ? ');
        return (
          <TouchableOpacity ref={'touchable'} disabled={this.state.disabled} style={correctStyles} accessibilityLabel={this.state.item.name} onPress={this.state.item.onPress.bind(this)}>
            <Text style={styles.mediumLabel}>{this.state.item.name}</Text>
          </TouchableOpacity>
        );
      }
    }
    
    export { MainButton as default }
    

    【讨论】:

      【解决方案3】:

      首先,我不认为将 disableditem 属性传递给 state。 您可以直接以这种方式执行并摆脱构造函数以及componentWillReceivePropscomponentWillReceiveProps 生命周期方法将很快被弃用,因此他们不鼓励使用它。

      如果可能,将事件处理程序与 item 道具分开。 这不是最好的方法

      render () {
        const { disabled, item, onPress } = this.props;
        const { name } = item;
        ...
        return (
          ...
          <TouchableOpacity
            disabled={disabled}
            style={disabled ? disabledStyle : normalStyle}
            accessibilityLabel={name}
            onPress={onPress}
          >
            <Text style={styles.mediumLabel}>{name}</Text>
          </TouchableOpacity>
          ...
        ); 
      }
      

      【讨论】:

        【解决方案4】:

        我没有足够的上下文来准确理解您在这里尝试实现的目标,但试试这个:

          <TouchableOpacity disabled={this.state.disabled} style={this.state.disabled ? disabledStyle : normalStyles} accessibilityLabel={this.state.item.name} onPress={this.state.item.onPress.bind(this)}>
            <Text style={styles.mediumLabel}>{this.state.item.name}</Text>
          </TouchableOpacity>
        

        关于 'this.state.item.onPress' 做什么,或者为什么你使用你在道具中传递的项目来首先更改道具,也没有足够的上下文。听起来你可以改进你实现这个的方式,如果你给我更多的背景,我可能会提供帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-11-23
          • 1970-01-01
          • 2021-12-14
          • 1970-01-01
          • 1970-01-01
          • 2018-08-20
          • 2019-07-13
          • 1970-01-01
          相关资源
          最近更新 更多