簡體   English   中英

當組件在 React Native 中重新渲染時,動態不透明度不會改變

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

我開始學習 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,但組件的外觀沒有改變。

不確定它是否是TouchableOpacity組件上的錯誤,但在單擊該組件之前,不透明度不會在重新渲染時更新

要解決您的問題,只需將可觸摸的內容包裝在視圖中並將不透明度應用於視圖而不是可觸摸

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

}

在我看來,正確的解決方案是使用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>
  );
}

接下來您可以在componentDidUpdatedisabled道具更改使用setOpacityTo方法:

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

如果您使用的是React Native 0.63 及更高版本,那么 Pressable 是更優雅的解決方案,它的 Opacity 更改按預期工作。

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

對我來說,當我還更改了disabled道具和不透明度時,它就起作用了。

我想問題是TouchableOpacity中的不透明度是一個Animated.Value ,它覆蓋了style道具中的值並且不會改變,當style道具發生變化時......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM