Before you read ->> I did try using the extraData props in my FlatList configuration but it does not seem to work properly (maybe because I'm using Redux to manage state?)
My FlatList renders data from my API (basically it displays user chat messages).
I have been able to make the FlatList refresh when each chat message is sent with this lifecycle method:
componentDidUpdate(prevProps) {
if (prevProps.messages !== this.props.messages) {
this.props.fetchActivityMessages(this.props.navigation.state.params.activityId);
}
}
On the outside it seems to work fine. However this causes multiple/infinite requests to my server for the data. For instance, if I console.log(this.props) on the chat screen, it continues to console.log infinitely.
This is obviously a major problem but it's the only way I found to make my list refresh with the new data without having to reload the screen.
When I attempted using the extraData prop, I tried the following:
extraData={() => {this.props.fetchActivityMessages()}}
extraData={this.props}
extraData={this.props.messages}
None of which made the FlatList refresh without having to reload the page.
Can anyone help? I feel like I'm either doing something wrong with the componentDidUpdate lifecycle method (causing it to make infinite requests) or I'm not using the extraData prop correctly.
My FlatList(Chat) Component
import { activityMessage, sendActivityMessage, fetchActivityMessages } from '../actions';
import ChatListItem from './ChatListItem';
const ROOT_URL = 'https://mydomain.herokuapp.com';
const io = require('socket.io-client/dist/socket.io');
const socket = io.connect(ROOT_URL);
class ActivityChatForm extends Component {
componentDidMount() {
this.props.fetchActivityMessages(this.props.navigation.state.params.activityId);
}
// Need to fix as it makes infinite requests to the server
//but so far the only way I could get the FlatList to refresh without reloading page
componentDidUpdate(prevProps) {
if (prevProps.messages !== this.props.messages) {
this.props.fetchActivityMessages(this.props.navigation.state.params.activityId);
}
}
handleSubmit = () => {
const { activityId } = this.props.navigation.state.params;
const { sendActivityMessage, messageBody } = this.props;
socket.emit('createMessage', {
from: 'MEE!!',
text: messageBody
}, (data) => {
console.log('Received it', data);
});
sendActivityMessage({
activityId,
messageBody
});
}
renderItem = (message) => {
return <ChatListItem message={message} navigation={this.props.navigation}/>;
}
renderList = () => {
return (
<View>
<FlatList
ref={(ref) => { this.flatListRef = ref; }}
data={this.props.messages}
renderItem={this.renderItem}
keyExtractor={(message, index) => index}
/>
</View>
);
}
render() {
return (
<View>
<CardSection>
{this.renderList()}
</CardSection>
<CardSection>
<Input
value={this.props.messageBody}
onChangeText={text => this.props.activityMessage({ prop: 'messageBody', value: text})}
placeholder="Type your message"
/>
</CardSection>
<CardSection>
<Button
onPress={() => this.handleSubmit()}
buttonText="Send Message"
/>
</CardSection>
</View>
);
}
}
const mapStateToProps = (state) => {
const { messageBody } = state.activityMessage;
const { messages, loading } = state.fetchActivityMessages;
return { messageBody, messages, loading };
};
export default connect(mapStateToProps, {
activityMessage,
sendActivityMessage,
fetchActivityMessages
})(ActivityChatForm);
My ChatListItem component (used to renderItem in FlatList)
class ChatListItem extends React.PureComponent {
render() {
const { messageBody } = this.props.message.item;
return (
<View>
<CardSection>
<Text style={styles.titleStyle}>{ messageBody }</Text>
</CardSection>
</View>
);
}
}
export default ChatListItem;
The fetchActivityMessages action creator. This is used to pull user message data from my API
export const fetchActivityMessages = (activityId) => {
return async (dispatch) => {
try {
dispatch({ type: FETCH_MESSAGES_INITIATE });
let token = await AsyncStorage.getItem('token');
let { data } = await axios.get(`${ROOT_URL}/activities/${activityId}/chat`, {
headers: { 'x-auth': `${token}` }
});
dispatch({
type: FETCH_MESSAGES_SUCCESS,
payload: data
});
} catch(error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
console.log(error.request);
} else {
console.log('Error', error.message);
}
console.log(error.config);
};
};
};