I am learning React Native and this is my first post at Stack Overflow.
I'm trying to re-render a button to make its disabled
property change from false
to true
when onPress
.
This button is being manually rendered insiderenderMessageImage
from react-native-gifted-chat.
I am doing it through a boolean in this.state
, however I see the state value updating on the logs but the button remains visually the same and it can be pressed again and again without actually changing its disabled
property.
I have in my Chat.js
class:
constructor(props) {
super(props);
this.state = {
isButtonDisabled: false
};
}
Then from Gifted Chat I call renderMessageImage
to show a custom message design when a message has an image:
renderMessageImage = (props) => {
return (
<View>
<Button
title="Disable Button"
disabled={this.state.isButtonDisabled}
onPress={() => this.disableButton(props.currentMessage.id)}
/>
</View>)
}
This custom design is just a button that should call another method and then disable self:
disableButton = async (message_id) => {
console.log("Disabling message_id: " + message_id); //This shows the msg_id correctly where the button is
console.log(this.state.isButtonDisabled); //This shows false
this.setState(previousState => ({
isButtonDisabled: true
}));
console.log(this.state.isButtonDisabled); //This shows true (should update button disabled property)
return true;
}
For what I have tested so far, I can see that state value of isButtonDisabled
is correctly changing from false
to true
, and as I have read, a change in the state should make the component re-render, but unfortunately it is not working that way.
More in-depth testing:
I then headed to GiftedChat.js
sources from the react-native-gifted-chat
to try debugging some of the code and see what is going on there.
What I found is that whenever I press my custom button, the componentDidUpdate
of GiftedChat.js
is being called twice:
componentDidUpdate(prevProps = {}) {
const { messages, text, inverted } = this.props;
console.log(this.props !== prevProps); //This is called twice per button click
if (this.props !== prevProps) {
//this.setMessages(messages || []); //I changed this line for the line below to directly update state
this.setState({ messages });
console.log(this.props !== prevProps); //This is called once per button click (first of the two calls)
}
if (inverted === false &&
messages &&
prevProps.messages &&
messages.length !== prevProps.messages.length) {
setTimeout(() => this.scrollToBottom(false), 200);
}
if (text !== prevProps.text) {
this.setTextFromProp(text);
}
}
Once all this checked, I see that the state is being updated and the GiftedChat.js
component and messages are being updated once per button click, however my button in renderMessageImage
is never re-rendering to properly show its new disabled
value and actually become disabled.
I am totally clueless what else to test, so I would really appreciate some help on what am I doing wrong.
Thank you very much in advance.
Edit: renderMessageImage
is called by GiftedChat on my Chat.js
class render()
section, then GiftedChat will call this.renderMessageImage
whenever a message has an image (eg. this.state.messages[i].image != undefined
). That part is working correctly, everything is being called as it should, just the re-render of the button status (disabled
) is not updating:
render() {
return (
<View style={{ flex: 1 }}>
<GiftedChat
messages={this.state.messages}
onSend={this.sendMessage}
user={this.user}
placeholder={"Write a message..."}
renderMessageImage={this.renderMessageImage}
/>
<KeyboardAvoidingView behavior={'padding'} keyboardVerticalOffset={80}/>
</View>
);
}