在 React Native 中使用带有 Hooks 的记忆选择器



我的 react 原生应用程序中的一个组件多次重新渲染,导致我的派生数据出现问题。 我正在使用Redux来存储我的状态,并使用Selector钩子来检索状态并在渲染期间使用它。我已经阅读了很多关于使用重新选择库来避免不必要的渲染和优化性能的信息,但我正在努力使用钩子应用于我的 ES6 代码。

这是我当前的代码

import { useSelector, useDispatch } from "react-redux";
import...
const MovieDetailScreen = (props) => {
const selectedMovie = useSelector((state) => state.moviemain.moviemain);
const selectedMovieCast = useSelector((state) => state.moviecast.moviecast);
const selectedMovieCrew = useSelector((state) => state.moviecast.moviecrew);
return (
<View style={styles.container}>
<View>
<Text style={styles.description} numberOfLines={3}>
{selectedMovie.name}
</Text>            
</View>
<View>
<Text style={styles.description} numberOfLines={3}>
{selectedMovie.overview}
</Text>            
</View>
<View>
<Text style={styles.description} numberOfLines={3}>
{selectedMovie.released_date}
</Text>            
</View>
<View style={styles.textLabelRow}>
{selectedMovie.genres.map((item, id) => {
return (
<Text
style={[styles.txtLabel, { backgroundColor: "#404040" }]}
key={id}
numberOfLines={1}
>
{item.name}
</Text>
);
})}
</View>
</View>
...
...
);
};

我想将重新选择应用于任何派生数据,在随附的示例代码中,它将是所选电影状态的流派参数的映射处理

{selectedMovie.genres.map((item, id) => {
return (
<Text
style={[styles.txtLabel, { backgroundColor: "#404040" }]}
key={id}
numberOfLines={1}
>
{item.name}
</Text>
);
})}

我还有另外几十个类似的场景,我需要过滤数据或计算总数,并且由于重新渲染,我经常出现错误。 我相信使用 Reselect,只有在状态发生变化时才会执行该函数。

我试图按照这里的例子,将我的状态选择移到我的组件之外,并像这样重组我的代码

import...
import { createSelector } from "reselect";
const getMovie = createSelector(
(state) => state.moviemain.moviemain,
(moviemain) => moviemain.moviemain.map((item) => item.genres)
);
export const GenresList = () => {
const genres = useSelector(getMovie);
return (
<Text
style={[styles.txtLabel, { backgroundColor: "#404040" }]}
numberOfLines={1}
>
{genres}
</Text>
);
};
const MovieDetailScreen = (props) => {
const selectedMovie = useSelector((state) => state.moviemain.moviemain);
const selectedMovieCast = useSelector((state) => state.moviecast.moviecast);
const selectedMovieCrew = useSelector((state) => state.moviecast.moviecrew);
return (
<View style={styles.container}>
....
....
<View>
<GenresList />            
</View>
</View>
...
...
);
};

但我在创建选择器函数中收到以下错误undefined 不是对象(评估 'moviemain.moviemain.map'(

我已经尝试了其他建议的解决方案,所有代码都在主要组件中,但我遇到了其他类型的错误。

我将不胜感激一些指导。

TLDR; 在下面的代码中,第一个参数返回moviemian.moviemain属性,下一行你想获取它的moviemain属性 - 意思是:moviemian.moviemain.moviemain,它是未定义的,所以你不能映射它。

const getMovie = createSelector(
(state) => state.moviemain.moviemain,
(moviemain) => moviemain.moviemain.map((item) => item.genres)
);

请记住:您在选择器中编写的内容会在第二个参数中得到结果。

解决方案:删除多余的电影主:

(moviemain) => moviemain.map((item) => item.genres)

Redux 选择器可能很棘手,这里有一个复习

// you can either use multiple selectors
// declare these outside of component 
const getSelectedMovie = (state) => state.moviemain.moviemain;
const getSelectedMovieCast = (state) => state.moviecast.moviecast;
const getSelectedMovieCrew = (state) => state.moviecast.moviecrew;
// or use one since its the same object
const getSelectedMovieAll = (state) => state.moviemain;
// so that you can use them inside component like
const MovieDetailScreen = (props) => {
const selectedMovie = useSelector(getSelectedMovie);
const movies = useSelector(getSelectedMovieAll);
// pay attention to the keys, they remain the same
const { moviecast: selectedMovieCast, moviecrew: selectedMovieCrew } = movies;
}

好吧,这是针对 redux 部分的,关于重新选择,您可以像这样使用它:

const example = createSelector(
[selector1, selector2]
(resultOfSelector1, resultOfSelector2) => ({ 'return': 'something'})
);
// so in case moviemain.moviemain is an array you can do the following
// make sure you reuse the previous selectors
const getMovie = createSelector(
[getSelectedMovie]
(moviemain) => moviemain.map((item) => item.genres)
);
export const GenresList = () => {
const genres = useSelector(getMovie);
return (

最新更新