我的react本机应用程序中的一个组件正在重新渲染几次,导致派生数据出现问题。 我正在使用 Redux 存储状态,并使用 useSelector 钩子检索状态并在渲染期间使用它。我已经阅读了很多有关使用Reselect库的信息,以避免不必要的渲染和优化性能,但是我一直在努力通过钩子将其应用于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>
...
...
);
};
我想将Reselect应用于任何派生数据,在附带的示例代码中,这将是selectedMovie状态的genres参数的映射处理
{selectedMovie.genres.map((item, id) => {
return (
<Text
style={[styles.txtLabel, { backgroundColor: "#404040" }]}
key={id}
numberOfLines={1}
>
{item.name}
</Text>
);
})}
我还有另外数十种类似的情况,需要过滤数据或计算总计,由于重新渲染,我经常会出错。 我相信使用Reselect时,只有在状态更改时才能执行该功能。
我试图通过将状态选择移到组件之外并像这样重组代码来遵循here中的示例
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>
...
...
);
};
但是在createSelector函数中出现以下错误 未定义不是对象(正在评估“ moviemain.moviemain.map”)
我尝试了其他建议的解决方案,这些解决方案在主要组件中包含所有代码,但是我遇到其他类型的错误。
我希望您能提供一些指导。
答案 0 :(得分:0)
TLDR ; 在下面的代码中,第一个参数返回moviemian.moviemain属性,而下一行要获取该属性的moviemain属性-意思是:moviemian.moviemain.moviemain,它是未定义的,因此您无法映射它。
plt.gca().set_color_cycle(['green', 'yellow'])
for dtype in ['Y', 'N']:
plt.plot(
'Datetime',
dtype,
data=df,
label=dtype,
alpha=0.8
)
plt.legend()
plt.grid()
plt.show()
记住:在选择器中编写的内容将在第二个参数中得到结果。
解决方案:删除多余的电影main:
const getMovie = createSelector(
(state) => state.moviemain.moviemain,
(moviemain) => moviemain.moviemain.map((item) => item.genres)
);
Redux选择器可能很棘手,这是一个复习
(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;
}