简体   繁体   English

当组件在 React Native 中重新渲染时,动态不透明度不会改变

[英]Dynamic Opacity not changing when component rerenders in react native

I'm starting to learn React Native, and for my project I created a simple Button component to reuse in my project.我开始学习 React Native,并为我的项目创建了一个简单的 Button 组件以在我的项目中重用。 I set the opacity value dynamically according to the variable 'disabled', however, the look of the button is not changing with the value of the opacity variable.我根据变量“禁用”动态设置了不透明度值,但是,按钮的外观不会随着不透明度变量的值而改变。 I searched around and I have not found an explanation..找了一圈也没找到解释
Any help will be appreciated.任何帮助将不胜感激。

Here is my source code:这是我的源代码:

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
    ])
}

EDIT: Here is the code the calls the button编辑:这是调用按钮的代码

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>
            )
    }
}

The disabled variable is true if the title of the newDeck component is empty or null.如果 newDeck 组件的标题为空或 null,则 disabled 变量为 true。 When this variable is true, the opacity of the button should be only 0.5.当这个变量为真时,按钮的不透明度应该只有 0.5。 When the value goes to false, then the opacity changes to 1 again.当该值变为 false 时,不透明度再次变为 1。 If I log the value of the opacity in the component, I can see it going from 0.5 to 1, but the look of the component doesn't change.如果我记录组件中不透明度的值,我可以看到它从 0.5 变为 1,但组件的外观没有改变。

not sure if it's a bug on the TouchableOpacity component, but the opacity won't update on a re-render until the component is clicked不确定它是否是TouchableOpacity组件上的错误,但在单击该组件之前,不透明度不会在重新渲染时更新

to fix your problem just wrap the content of the touchable in a View and apply the opacity to the view instead of the touchable要解决您的问题,只需将可触摸的内容包装在视图中并将不透明度应用于视图而不是可触摸

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>
    )

}

In my opinion correct solution is to use setOpacityTo method.在我看来,正确的解决方案是使用setOpacityTo方法。

In your render :在你的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>
  );
}

And next you can use setOpacityTo method in componentDidUpdate on disabled props change:接下来您可以在componentDidUpdatedisabled道具更改使用setOpacityTo方法:

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

If you are using React Native version 0.63 onwards then Pressable is more elegant solution to go with and its Opacity change works as expected.如果您使用的是React Native 0.63 及更高版本,那么 Pressable 是更优雅的解决方案,它的 Opacity 更改按预期工作。

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

For me it worked when I also changed the disabled prop together with the opacity.对我来说,当我还更改了disabled道具和不透明度时,它就起作用了。

I guess the issue is that the opacity in TouchableOpacity is an Animated.Value that overrides the value in the style prop and doesn't change, when the style prop changes...我想问题是TouchableOpacity中的不透明度是一个Animated.Value ,它覆盖了style道具中的值并且不会改变,当style道具发生变化时......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM