【问题标题】:Dynamic Opacity not changing when component rerenders in react native当组件在本机反应中重新呈现时,动态不透明度不会改变
【发布时间】:2018-06-07 08:55:24
【问题描述】:

我开始学习 React Native,并为我的项目创建了一个简单的 Button 组件以在我的项目中重用。我根据变量“禁用”动态设置不透明度值,但是,按钮的外观不会随着不透明度变量的值而改变。我四处寻找,我没有找到解释..
任何帮助将不胜感激。

这是我的源代码:

import React from 'react'
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
import PropTypes from 'prop-types'

//TODO: arrumar o problema com a opacidade
export default function Button({text, onPress, style, disabled, textStyle}) {
    let opacity = disabled === true ? 0.5 : 1
    // console.log('opacity', opacity)
    return (
        <TouchableOpacity onPress={onPress} style={[defaultStyles.button, style, {opacity: opacity}]} 
            disabled={disabled}>
            <Text style={[defaultStyles.text, textStyle]}>{text}</Text>
        </TouchableOpacity>
    )

}

const defaultStyles = StyleSheet.create({
    text: {
        color: 'white'
    },
    button: {
        backgroundColor: 'black',
        margin: 15,
        padding: 15,
        borderRadius: 10
    },
})

Button.propTypes = {
    text: PropTypes.string,
    onPress: PropTypes.func,
    style: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.array,
        PropTypes.object
    ]),
    disabled: PropTypes.bool,
    textStyle: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.array,
        PropTypes.object
    ])
}

编辑: 这是调用按钮的代码

class NewDeck extends Component {

    state={
        title: null
    }

    submit = () => {
        const { add, goBack } = this.props
        let deck = {...this.state}
        if(!deck['deckId']){
            deck['deckId'] = Date.now()
            deck['logs'] = []
        }

        !deck['cardsId'] && (deck['cardsId'] = [])

        add(deck).then(() => {
            this.props.navigation.navigate('Deck', {deckId: deck.deckId, title: deck.title})
            this.setState({title: null})
            }
        )
    }

    render(){
        const disabled = this.state.title === null || this.state.title.length === 0
        return (
            <KeyboardAwareScrollView resetScrollToCoords={{ x: 0, y: 0 }}
                contentContainerStyle={styles.container}>
                <Text style={textStyles.title2}>Whats the title of your deck?</Text>
                    <TextInput editable={true} style={[styles.input, textStyles.body]}
                    placeholder='Type title here'
                    maxLength={25}
                    value={this.state.title}
                    onChangeText={(text) => {
                        this.setState({title: text})
                    }}
                    />
                <Button
                    onPress={this.submit}
                    text='Submit'
                    style={{backgroundColor: colors.pink}}
                    textStyle={textStyles.body}
                    disabled={!this.state.title} 
                />
              </KeyboardAwareScrollView>
            )
    }
}

如果 newDeck 组件的标题为空或 null,则 disabled 变量为 true。当这个变量为真时,按钮的不透明度应该只有 0.5。当该值变为 false 时,不透明度再次变为 1。如果我记录组件中的不透明度值,我可以看到它从 0.5 变为 1,但组件的外观没有改变。

【问题讨论】:

  • 代码中的任何内容都无法控制动态呈现。你想做什么?
  • 只是一个按钮,如果禁用变量为真,则不透明度会发生变化。
  • 让我们看看你是如何使用那个按钮的
  • @FacundoLaRocca 我提供了更多信息!
  • 你能把不透明度放在TouchableOpacity文本里面,看看它是否改变

标签: javascript reactjs react-native opacity touchableopacity


【解决方案1】:

对我来说,当我还更改了 disabled 属性和不透明度时,它就起作用了。

我猜问题是TouchableOpacity 中的不透明度是一个Animated.Value,它会覆盖style 道具中的值并且不会改变,当style 道具发生变化时...

【讨论】:

    【解决方案2】:

    如果您使用的是 React Native 0.63 版 及更高版本,那么 Pressable 是更优雅的解决方案,它的不透明度更改按预期工作。

    <Pressable
        style={{
           opacity: item.isSelected ? 0.5 : 1
        }}>
           //Your button content goes here
    </Pressable>
    

    【讨论】:

      【解决方案3】:

      我认为正确的解决方案是使用setOpacityTo 方法。

      在你的render

      render() {
        const opacityValue = this.props.disabled ? 0.5 : 1;
        return (
          <TouchableOpacity style={{ opacity: opacityValue }} ref={(btn) => { this.btn = btn; }} onPress={this.onPress}>
            <Text>{this.props.text}</Text>
          </TouchableOpacity>
        );
      }
      

      接下来你可以在componentDidUpdate 中使用setOpacityTo 方法对disabled 的道具进行更改:

        componentDidUpdate(prevProps) {
          const { disabled } = this.props;
          if (disabled !== prevProps.disabled) {
            const opacityValue = disabled ? 0.5 : 1;
            this.btn.setOpacityTo(opacityValue);
          }
        }
      

      【讨论】:

        【解决方案4】:

        不确定是否是 TouchableOpacity 组件上的错误,但在单击组件之前,不透明度不会在重新渲染时更新

        要解决您的问题,只需将可触摸的内容包装在 View 中,然后将 opacity 应用于视图而不是可触摸

        export default function Button({text, onPress, style, disabled, textStyle}) {
            const opacity = disabled === true ? 0.5 : 1
            // console.log('opacity', opacity)
            return (
                <TouchableOpacity onPress={onPress} disabled={disabled} 
                  style={[defaultStyles.button, style]}>
                  <View style={{opacity}}>
                    <Text style={[defaultStyles.text, textStyle]}>{text}</Text>
                  </View>
                </TouchableOpacity>
            )
        
        }
        

        【讨论】:

        • 很高兴,如果对您有用,请确保将答案标记为正确。
        • 你救了我的命。谢谢
        • 在不点击组件的情况下更新不透明度已与您的解决方法一起使用,但仍然不透明度已延迟更新。有什么办法解决吗?
        • 不要只对可触摸的视图应用不透明度
        猜你喜欢
        • 2018-06-24
        • 1970-01-01
        • 2021-07-10
        • 1970-01-01
        • 1970-01-01
        • 2018-10-05
        • 2023-02-03
        • 2020-10-19
        • 2019-01-21
        相关资源
        最近更新 更多