Перед прочтением - >> Я попытался использовать реквизиты extraData в моей конфигурации FlatList, но, похоже, он не работает должным образом (возможно, потому что я использую Redux для управления состоянием?)
Мой FlatList отображает данные из моего API (в основном это отображает сообщения чата пользователя).
Мне удалось обновить FlatList при отправке каждого сообщения чата с помощью этого метода жизненного цикла:
componentDidUpdate(prevProps) {
if (prevProps.messages !== this.props.messages) {
this.props.fetchActivityMessages(this.props.navigation.state.params.activityId);
}
}
Снаружи вроде бы нормально работает. Однако это вызывает многократные / бесконечные запросы к моему серверу для данных. Например, если я console.log (this.props) на экране чата, он продолжает console.log бесконечно.
Это, очевидно, серьезная проблема, но я нашел единственный способ сделать так, чтобы мой список обновлялся новыми данными без перезагрузки экрана.
Когда я попытался использовать опору extraData, я попытался сделать следующее:
extraData={() => {this.props.fetchActivityMessages()}}
extraData={this.props}
extraData={this.props.messages}
Ничто из этого не привело к обновлению FlatList без перезагрузки страницы.
Кто-нибудь может помочь? Я чувствую, что либо делаю что-то не так с методом жизненного цикла componentDidUpdate (вызывая бесконечные запросы), либо неправильно использую опцию extraData.
Мой компонент FlatList (Chat)
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);
Мой компонент ChatListItem (используется для визуализации элемента в 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;
Создатель действия fetchActivityMessages. Это используется для извлечения данных сообщений пользователя из моего 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);
};
};
};