如何反应原生重新渲染 Flatlist?
Posted
技术标签:
【中文标题】如何反应原生重新渲染 Flatlist?【英文标题】:How to do react native re-render Flatlist? 【发布时间】:2021-12-28 01:51:03 【问题描述】:如何做 react native 重新渲染 Flatlist?
使用Effect检查tagId的数据并弹出一个新页面,直到tagId存在。
使用use Effect导入的数据不会传递给renderItem,而只会传递第一页的数据。
如何将更新后的数据从 useEffect 转发到 renderItem?
app.tsx
const App: () => Node = () =>
const Stack = createNativeStackNavigator();
const [accessToken, setAccessToken] = useState("");
const [isSearchHidden, setIsSearchHidden] = useState(false);
const [isHomeHidden, setIsHomeHidden] = useState(false);
const [id, setId] = useState("");
const [tagId, setTagId] = useState("");
const [chargeAmount, setChargeAmount] = useState("");
const value =
setAccessToken: setAccessToken,
isSearchHidden: isSearchHidden,
setIsSearchHidden: setIsSearchHidden,
isHomeHidden: isHomeHidden,
setIsHomeHidden: setIsHomeHidden,
id: id,
setId: setId,
tagId: tagId,
setTagId: setTagId,
chargeAmount: chargeAmount,
setChargeAmount: setChargeAmount,
;
useEffect(() =>
AsyncStorage.getItem("@user", (_: any, result: any) =>
// console.log("user: ",result)
if (result)
// result가 있을때만 accessToken 저장
setAccessToken(result);
);
, []);
const errorLink = onError(( graphQLErrors, operation, forward ) =>
if (graphQLErrors)
for (const err of graphQLErrors)
if (err.extensions?.code === "UNAUTHENTICATED")
operation.setContext(
headers:
...operation.getContext().headers,
authorization: `Bearer $getAccessToken(setAccessToken)`,
,
);
return forward(operation);
);
const uploadLink = createUploadLink(
uri: "https://backend03-team.codebootcamp.co.kr/team05",
headers:
authorization: `Bearer $accessToken`,
,
credentials: "include",
);
const client = new ApolloClient(
cache: new InMemoryCache(),
link: ApolloLink.from([errorLink, uploadLink as unknown as ApolloLink]),
);
return (
<GlobalContext.Provider value=value>
<ApolloProvider client=client>
<NavigationContainer>
<Stack.Navigator screenOptions= headerShown: false >
accessToken ? (
<Stack.Screen name="tabNavigator" component=TabNavigator />
) : (
<Stack.Screen name="Login" component=LoginNavigator />
)
</Stack.Navigator>
</NavigationContainer>
</ApolloProvider>
</GlobalContext.Provider>
);
;
export default App;
container
const ListContainer = () =>
const [aaa, setAaa] = useState(1);
const data, fetchMore, refetch = useQuery(FETCH_USED_ITEMS,
variables:
page: 1,
isSoldout: false,
,
);
useEffect(() =>
console.log("9999", data);
const result = data?.fetchUseditems.some((el) =>
return el.tags[0] === tagId;
);
console.log("33332232111", result);
console.log("989898", tagId);
if (result === false)
onLoadMore();
else
return;
console.log("443432", aaa);
, [data?.fetchUseditems]);
const setId, id, setTagId, tagId = useContext(GlobalContext);
const onPressDetail = (el) =>
setId(el._id);
console.log("555", el._id);
console.log("433", id);
;
const onPressListCategory = (value) =>
setTagId(value);
;
const onLoadMore = () =>
// if (!data)
// return;
//
fetchMore(
variables:
page: Math.ceil(data?.fetchUseditems.length / 10) + 1,
,
updateQuery: (prev, fetchMoreResult ) =>
return
fetchUseditems: [
...prev.fetchUseditems,
...fetchMoreResult.fetchUseditems,
],
;
,
);
;
return (
<ListUI
data=data
onPressDetail=onPressDetail
onPressListCategory=onPressListCategory
onLoadMore=onLoadMore
setAaa=setAaa
aaa=aaa
fetchMore=fetchMore
refetch=refetch
/>
);
;
presenter
const ListUI = (props) =>
const tagId, setTagId, setAaa = useContext(GlobalContext);
const navigation = useNavigation();
const renderItem = ( item : any) =>
console.log("***********************", item);
return (
<>
item.tags[0]?.includes(tagId) && (
<DetailProductWrapper key=item._id>
<ProductImageWrapper
onPress=() =>
navigation.navigate("상품 상세보기",
id: props.onPressDetail(item),
)
>
<ProductImage
source=
uri: `https://storage.googleapis.com/$item.images[0]`,
/>
</ProductImageWrapper>
<InfoWrapper>
<InfoTextWrapper>
<InfoTitle>item.name</InfoTitle>
<InfoPrice>item.price원</InfoPrice>
</InfoTextWrapper>
<InfoFavoriteImage
source=require("../../../public/images/list/infofavorite.png")
/>
</InfoWrapper>
</DetailProductWrapper>
)
</>
);
;
console.log("================", props.data);
console.log("6666", props.aaa);
return (
<ListView>
<HeaderAnimation onPressListCategory=props.onPressListCategory />
<FlatList
data=props.data?.fetchUseditems
renderItem=renderItem
keyExtractor=(item) => item.id
onEndReached=props.onLoadMore
extraData=props.data
onEndReachedThreshold=0.8
></FlatList>
</ListView>
);
;
数据控制台捕获 enter image description here
renderItem 控制台捕获 enter image description here
【问题讨论】:
【参考方案1】:通过将 extraData=this.state 传递给 FlatList,我们确保 FlatList 本身会在状态更改时重新渲染。如果不设置此 prop,FlatList 将不知道它需要重新渲染任何项目,因为它是一个 PureComponent,并且 prop 比较不会显示任何更改。
Flatlist Doc
【讨论】:
以上是关于如何反应原生重新渲染 Flatlist?的主要内容,如果未能解决你的问题,请参考以下文章