如何为每条气泡消息设置 ID,然后使用其 ID 进行更新

how to set ID for every bubble message and then update using its ID

了解我的问题的简单方法播放以下视频,看看我的问题是什么。 https://vimeo.com/315390850

如果您的互联网连接不佳,请阅读以下句子。

我要更新气泡消息,但我不知道如何通过 Id 更新特定消息。 示例:在 html 中,列表中的每个标签都有一个 Id,如果我们必须更新,那么我们 select 通过 id 然后更新它。 那么如何为 react-native-gifted-chat 气泡消息制作这样的概念?

我尝试将 refs 与 setNativeProps 函数一起使用,但没有成功。

render(){
 return (
   <GiftedChat
         extraData={this.state}
         messages={this.state.messages}
          onSend={messages => this.onSend(messages)}
          user={{
              _id: this.state.userId,
           }}
           renderBubble={this.renderBubble}
           renderInputToolbar={this.renderInputToolbar.bind(this)}
      />
 );
}

renderBubble = props => {
        if (props.currentMessage.audio) {
            return (
                <View style={[{ width: 150, height: 70, backgroundColor: 'lightgray' }, props.position === 'left' ? { left: -41 } : {}]}>
                    <EIcon
                        name="google-play"
                        size={30}
                        color={this.state.playAudio ? "red" : "blue"}
                        style={{
                            left: 90,
                            position: "relative",
                            shadowColor: "#000",
                            shadowOffset: { width: 0, height: 0 },
                            shadowOpacity: 0.5,
                            backgroundColor: "transparent"
                        }}
                        onPress={() => {
                            this.setState({
                                playAudio: true
                            });
                            const sound = new Sound(props.currentMessage.audio, "", error => {

                                if (error) {
                                    console.log("failed to load the sound", error);
                                }

                                const duration = sound.getDuration();
                                const progressPhase = 1 / duration;

                                if (duration !== 0) {
                                    this._interval = setInterval(() => {

                                        this.setState({
                                            progress: this.state.progress += progressPhase
                                        });

                                        if (this.state.progress >= 1) {
                                            clearInterval(this._interval);
                                            this.setState({
                                                progress: 0.0,
                                                playAudio: false
                                            });
                                        }

                                    }, 1000);
                                }

                                sound.play(success => {
                                    console.log(success, "success play");
                                    if (!success) {
                                        Alert.alert("There was an error playing this audio");
                                    }
                                });

                            });
                        }}
                    />


                    <Progress.Circle progress={this.state.progress} showsText size={35} />

                </View>
            );
        } else {
            return (
                <Bubble
                    {...props}
                    textStyle={{
                        right: {
                            color: '#fff',
                        },
                        left: {
                            color: '#fff',
                        },
                    }}
                    wrapperStyle={{
                        left: {
                            backgroundColor: "orange",
                            left: -41
                        },
                        right: {
                            backgroundColor: 'green'
                        }
                    }}
                />
            );
        }
    }

这里我有一个聊天框,当我发送多个音频消息时,例如 3 aduio 消息:音频消息 .1,音频消息 .2,音频消息 .3 Aduio 消息 .1 是第一次来。 aduio message .3 上次来了

每条音频消息都有一个播放图标和一个进度条。 当我点击播放图标时,我会更新进度条。 这里我使用间隔来点击播放图标,进度条会多次更新直到完成。

我的问题是:当我单击音频消息 .1 的播放图标时,只会更新最后一条音频消息 .3。 我想:如果我点击音频消息 .1,音频消息 .1 的进度条应该更新。音频消息 .2 和音频消息 .3 相同。

我通过条件渲染解决了我的问题我还更改了 class 并添加了 这一行:next.audio == current.audio ||

export default class Message extends React.Component {

  shouldComponentUpdate(nextProps) {
    const next = nextProps.currentMessage;
    const current = this.props.currentMessage;
    const { nextMessage } = this.props;
    const nextPropsMessage = nextProps.nextMessage;
    return (
      next.send !== current.send ||
      next.received !== current.received ||
      next.pending !== current.pending ||
      next.createdAt !== current.createdAt ||
      next.text !== current.text ||
      next.image !== current.image ||
      next.video !== current.video ||
      next.audio == current.audio ||  // this line added by me
      nextMessage !== nextPropsMessage
    );
  }

 //..............

}

我添加了这个条件,请让我知道性能。这条树线,我添加到我的代码中:

this.myPro = <Progress.Circle progress={this.state.progress} showsText size={35} />; this.setState({currentPlayedMessage: props.currentMessage._id }); { props.currentMessage._id === this.state.currentPlayedMessage ? this.myPro : null }

所有代码:

if (props.currentMessage.audio) {

            this.myPro = <Progress.Circle progress={this.state.progress} showsText size={35} />; // this line added

            return (
                <View style={[{ width: 150, height: 70, backgroundColor: 'lightgray' }, props.position === 'left' ? { left: -41 } : {}]}>
                    <EIcon
                        name="google-play"
                        size={30}
                        color={this.state.playAudio ? "green" : "blue"}
                        style={{
                            left: 90,
                            position: "relative",
                            shadowColor: "#000",
                            shadowOffset: { width: 0, height: 0 },
                            shadowOpacity: 0.5,
                            backgroundColor: "transparent"
                        }}
                        onPress={() => {

                            this.setState({
                                playAudio: true,
                                currentPlayedMessage: props.currentMessage._id // this line added
                            });

                            const sound = new Sound(props.currentMessage.audio, "", error => {

                                if (error) {
                                   return;
                                }

                                const duration = sound.getDuration();
                                const progressPhase = 1 / duration;

                                if (duration !== 0) {
                                    this._interval = setInterval(() => {

                                        this.setState({
                                            progress: this.state.progress += progressPhase
                                        });

                                        if (this.state.progress >= 1) {
                                            clearInterval(this._interval);
                                            this.setState({
                                                progress: 0.0,
                                                playAudio: false
                                            });
                                        }

                                    }, 1000);
                                }

                                sound.play(success => {
                                    console.log(success, "success play");
                                    if (!success) {
                                        Alert.alert("There was an error playing this audio");
                                    }
                                });

                            });
                        }}
                    />


                    { props.currentMessage._id === this.state.currentPlayedMessage ? this.myPro : null } // this line added

                </View>
            );
        }

我遇到了同样的问题,但我在功能组件中这样解决了。 首先你在天赋聊天组件

中添加shouldUpdateMessage
 <GiftedChat
     messages={messages}
      onSend={messages => onSend(messages)}
       renderBubble={renderBubble}
       renderInputToolbar={renderInputToolbar.bind(this)}
       shouldUpdateMessage={(props, nextProps) => { return props.currentMessage.audio == nextProps.currentMessage.audio ? true : false }}        // Add this in your gifted chat

  />

然后我在渲染方法中这样解决了它,我刚刚使用了我的代码,但你可以按照相同的方法。

if (currentMessage.audio) {
       
        const icon=        <Icon key={currentMessage.key} name={'play-arrow'} size={30} type="material" color={ 'blue'} />
        const icon2=        <Icon key={currentMessage.key} name={'multitrack-audio' } size={30} type="material" color={'red'} />
        
        return (
            <TouchableOpacity key={currentMessage.key} onPress={() => {
                setCurrentPlayedMessage(currentMessage.key)

            }} >
               { props.currentMessage.key === currentPlayedMessage ? icon2: icon }     //This Line is responsible for changing a specific message, you can use your component in ternary operator after condition
            </TouchableOpacity>
        )
    }
    
    return (
        <Bubble

            {...props} />