在您阅读之前 - >>我确实尝试在我的FlatList配置中使用extraData道具但它似乎无法正常工作(可能是因为我使用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 prop时,我尝试了以下方法:
extraData={() => {this.props.fetchActivityMessages()}}
extraData={this.props}
extraData={this.props.messages}
其中没有一个能够在不重新加载页面的情况下刷新FlatList .
有人可以帮忙吗?我觉得我在使用componentDidUpdate生命周期方法做错了(导致它发出无限请求)或者我没有正确使用extraData prop .
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);
};
};
};
1 回答
首先摆脱“componentDidUpdate()” . 就像你说的那样不断触发 . 这是因为在屏幕上执行的每个操作上,其调用“componentDidUpdate” .
其次,extraData属性需要传递一个状态对象属性,而不是道具 . 使用道具它什么都不做 . 所以在你的代码中,我认为你需要做以下事情:
我说我想是因为我不确定redux部分 . Redux管理您的应用程序状态,但我认为您仍然可以在各个屏幕中设置状态对象 . 我再次不确定 . 我每天都使用React-Native工作,但不是Redux . 希望有些帮助 :)