如何为每条气泡消息设置 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} />
了解我的问题的简单方法播放以下视频,看看我的问题是什么。 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} />