在您阅读之前 - >>我确实尝试在我的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。
我的FlatList(聊天)组件
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中的renderItem)
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);
};
};
};
答案 0 :(得分:0)
首先摆脱&#34; componentDidUpdate()&#34;。就像你说的那样不断触发。这是因为在屏幕上执行的每个操作,其调用&#34; componentDidUpdate&#34;。
其次,extraData属性需要将状态对象属性传递给它,而不是道具。使用道具它什么都不做。因此,在您的代码中,我认为您需要执行以下操作:
state = {};
...
componentDidMount() {
const myData = this.props.fetchActivityMessages
(this.props.navigation.state.params.activityId);
this.setState({
data: myData
})
}
....
<FlatList
ref={(ref) => { this.flatListRef = ref; }}
data={this.props.messages}
extraData={this.state.data}
renderItem={this.renderItem}
keyExtractor={(message, index) => index}
/>
我说我想是因为我不确定redux部分。 Redux管理您的应用程序状态,但我认为您仍然可以在各个屏幕中设置状态对象。我不完全确定。我每天都使用React-Native工作,但不是Redux。希望其中一些有用:)