当数据属性更改时,本机 FlatList 不会重新渲染
react native FlatList not rerendering when data prop changes
我有一个 FlatList
组件,它使用 Redux(间接)作为 data
道具的来源。见下文
const mapStateToProps = state => ({
rdx_activeUsers: state.profile.activeUsers,
});
convertRdxActiveUsersObjectToUsableArray = () => {
let activeUsersArray = [];
Object.values(this.props.rdx_activeUsers).forEach(userObj => {
activeUsersArray.push(userObj);
});
return activeUsersArray;
};
//-----------------------------------------------------------------------
render() {
let usableArray4FlatList = this.convertRdxActiveUsersObjectToUsableArray();
return (
<View>
<FlatList
data={usableArray4FlatList}
每当在 Firebase DB 中添加或删除活动用户时,我都会有增加或减少 Redux 对象大小的侦听器 rdx_activeUsers
.......目标是 Redux 中的此更改应该触发 render()
函数(由于在 convertRdxActiveUsersToUsableArray
函数中使用了 Redux....它存在于 render()
函数中)。
我可以通过调试工具看到,每当我添加或删除用户时,Redux rdx_activeUsers
对象 都会正确更新...但是 FlatList 仅在我 添加 用户时动态重新呈现(即 Redux 对象 rdx_activeUsers
大小增加)...但当我 删除 一个(即 Redux 对象 rdx_activeUsers
减小大小)。
我也试过添加 prop extraData={this.props.rdx_activeUsers}
...但这没有任何区别
12 月 31 日更新
下面是我的减速器......
case ACTIVE_USER_CHILD_ADDED
正在成功更新 Redux AND 触发重新渲染
case ACTIVE_USER_CHILD_REMOVED
正在成功更新 Redux 但不会 触发重新渲染....看起来问题就出在这里
case ACTIVE_USER_CHILD_ADDED:
const key2Add = action.payload.userId;
const val2Add = action.payload;
return { ...state, activeUsers: { ...state.activeUsers, [key2Add]: val2Add } };
case ACTIVE_USER_CHILD_CHANGED:
const key2Updel = action.payload.userId;
const val2Updel = action.payload;
if (val2Updel.active) {
return { ...state, activeUsers: { ...state.activeUsers,[key2Updel]: val2Updel } };
}
if (state.activeUsers) {
const updatedstate = state;
delete updatedstate.activeUsers[key2Updel];
return {...updatedstate};
}
//else
return state;
case ACTIVE_USER_CHILD_REMOVED:
const key2Del = action.payload.userId;
const oldState = state;
delete oldState.activeMsgUsers[key2Del];
return {...oldState};
下面是我的动作创作者
export const _actActiveUserChildAdded = userObj => {
return {
type: ACTIVE_USER_CHILD_ADDED,
payload: userObj,
};
};
export const _actActiveUserChildChanged = userObj => {
return {
type: ACTIVE_USER_CHILD_CHANGED,
payload: userObj,
};
};
export const _actActiveUserChildRemoved = userObj => {
return {
type: ACTIVE_USER_CHILD_REMOVED,
payload: userObj,
};
};
试试这个
const mapStateToProps = state => ({
rdx_activeUsers: state.profile.activeUsers,
});
//-----------------------------------------------------------------------
render() {
let activeUsersArray = [];
Object.values(this.props.rdx_activeUsers).forEach(userObj => {
activeUsersArray.push(userObj);
});
return (
<View>
<FlatList
data={activeUsersArray}
这段代码不会触发重新渲染
case ACTIVE_USER_CHILD_REMOVED:
const key2Del = action.payload.userId;
const oldState = state;
delete oldState.activeMsgUsers[key2Del];
return {...oldState};
通过返回 {...oldState}
,this.state
中的所有引用保持不变,不会触发更新
快速解决
用return {...oldState, activeMsgUsers: {...activeMsgUsers}}
代替
更好的解决方案
不要使用 delete
,而是使用 Array.filter
来创建新的对象引用
最佳解决方案
将您的组件重构为挂钩并使 activeMsgUsers
成为独立状态,如果您正确执行,调用 setActiveMsgUsers
返回解构的旧状态,您就不会遇到这个问题
更改大小写 ACTIVE_USER_CHILD_REMOVED
就像遵循它应该工作一样,您正在修改正在改变状态对象而不是返回新对象的对象。
case ACTIVE_USER_CHILD_REMOVED:
const key2Del = action.payload.userId;
const {activeUsers:{[key2Del]:_,...restActiveUsers}} = state;
return {...state,activeUsers:{...restActiveUsers}};
我有一个 FlatList
组件,它使用 Redux(间接)作为 data
道具的来源。见下文
const mapStateToProps = state => ({
rdx_activeUsers: state.profile.activeUsers,
});
convertRdxActiveUsersObjectToUsableArray = () => {
let activeUsersArray = [];
Object.values(this.props.rdx_activeUsers).forEach(userObj => {
activeUsersArray.push(userObj);
});
return activeUsersArray;
};
//-----------------------------------------------------------------------
render() {
let usableArray4FlatList = this.convertRdxActiveUsersObjectToUsableArray();
return (
<View>
<FlatList
data={usableArray4FlatList}
每当在 Firebase DB 中添加或删除活动用户时,我都会有增加或减少 Redux 对象大小的侦听器 rdx_activeUsers
.......目标是 Redux 中的此更改应该触发 render()
函数(由于在 convertRdxActiveUsersToUsableArray
函数中使用了 Redux....它存在于 render()
函数中)。
我可以通过调试工具看到,每当我添加或删除用户时,Redux rdx_activeUsers
对象 都会正确更新...但是 FlatList 仅在我 添加 用户时动态重新呈现(即 Redux 对象 rdx_activeUsers
大小增加)...但当我 删除 一个(即 Redux 对象 rdx_activeUsers
减小大小)。
我也试过添加 prop extraData={this.props.rdx_activeUsers}
...但这没有任何区别
12 月 31 日更新
下面是我的减速器......
case ACTIVE_USER_CHILD_ADDED
正在成功更新 Redux AND 触发重新渲染
case ACTIVE_USER_CHILD_REMOVED
正在成功更新 Redux 但不会 触发重新渲染....看起来问题就出在这里
case ACTIVE_USER_CHILD_ADDED:
const key2Add = action.payload.userId;
const val2Add = action.payload;
return { ...state, activeUsers: { ...state.activeUsers, [key2Add]: val2Add } };
case ACTIVE_USER_CHILD_CHANGED:
const key2Updel = action.payload.userId;
const val2Updel = action.payload;
if (val2Updel.active) {
return { ...state, activeUsers: { ...state.activeUsers,[key2Updel]: val2Updel } };
}
if (state.activeUsers) {
const updatedstate = state;
delete updatedstate.activeUsers[key2Updel];
return {...updatedstate};
}
//else
return state;
case ACTIVE_USER_CHILD_REMOVED:
const key2Del = action.payload.userId;
const oldState = state;
delete oldState.activeMsgUsers[key2Del];
return {...oldState};
下面是我的动作创作者
export const _actActiveUserChildAdded = userObj => {
return {
type: ACTIVE_USER_CHILD_ADDED,
payload: userObj,
};
};
export const _actActiveUserChildChanged = userObj => {
return {
type: ACTIVE_USER_CHILD_CHANGED,
payload: userObj,
};
};
export const _actActiveUserChildRemoved = userObj => {
return {
type: ACTIVE_USER_CHILD_REMOVED,
payload: userObj,
};
};
试试这个
const mapStateToProps = state => ({
rdx_activeUsers: state.profile.activeUsers,
});
//-----------------------------------------------------------------------
render() {
let activeUsersArray = [];
Object.values(this.props.rdx_activeUsers).forEach(userObj => {
activeUsersArray.push(userObj);
});
return (
<View>
<FlatList
data={activeUsersArray}
这段代码不会触发重新渲染
case ACTIVE_USER_CHILD_REMOVED:
const key2Del = action.payload.userId;
const oldState = state;
delete oldState.activeMsgUsers[key2Del];
return {...oldState};
通过返回 {...oldState}
,this.state
中的所有引用保持不变,不会触发更新
快速解决
用return {...oldState, activeMsgUsers: {...activeMsgUsers}}
代替
更好的解决方案
不要使用 delete
,而是使用 Array.filter
来创建新的对象引用
最佳解决方案
将您的组件重构为挂钩并使 activeMsgUsers
成为独立状态,如果您正确执行,调用 setActiveMsgUsers
返回解构的旧状态,您就不会遇到这个问题
更改大小写 ACTIVE_USER_CHILD_REMOVED
就像遵循它应该工作一样,您正在修改正在改变状态对象而不是返回新对象的对象。
case ACTIVE_USER_CHILD_REMOVED:
const key2Del = action.payload.userId;
const {activeUsers:{[key2Del]:_,...restActiveUsers}} = state;
return {...state,activeUsers:{...restActiveUsers}};