React Native 选择器memoized在调用时返回根状态,Redux-ToolKit

f0brbegy  于 2023-06-24  发布在  React
关注(0)|答案(1)|浏览(92)

我使用的是reduxtoolkit的useSelector,每次我运行我的应用。我的应用程序重新渲染5次,我一直得到这个错误。我似乎找不到一个方法来摆脱这个错误。
选择器memoized在调用时返回根状态。这可能会导致不必要的还原。返回整个状态的选择器几乎可以肯定是一个错误,因为每当状态中的 * 任何 * 改变时,它们都会导致重新呈现。

*AppNavigator.tsx

const AppNavigator: FC<Props> = props => {
  const {loggedIn, busy} = useSelector(getAuthState);
  const dispatch = useDispatch();
  console.log('render');
  useEffect(() => {
    const fetchAuthInfo = async () => {
      try {
        dispatch(updateBusyState(true));
        const token = await getFromAsyncStorage(Keys.AUTH_TOKEN);
        if (!token) {
          return dispatch(updateBusyState(false));
        }

        const {data} = await client.get('/auth/is-auth', {
          headers: {
            Authorization: 'Bearer ' + token,
          },
        });
        dispatch(updateProfile(data.profile));
        dispatch(updateLoggedInState(true));
      } catch (error) {
        console.log('Auth error: ', error);
      }
      dispatch(updateBusyState(false));
    };
    fetchAuthInfo();
  }, []);

  return (
    <NavigationContainer theme={AppTheme}>
      {busy ? (
        <View
          style={{
            ...StyleSheet.absoluteFillObject,
            backgroundColor: colors.OVERLAY,
            zIndex: 1,
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <Loader />
        </View>
      ) : null}
      {loggedIn ? <TabNavigator /> : <AuthNavigator />}
    </NavigationContainer>
  );
};

Slice.tsx*

const slice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    updateProfile(authState, {payload}: PayloadAction<UserProfile | null>) {
      authState.profile = payload;
    },
    updateLoggedInState(authState, {payload}) {
      authState.loggedIn = payload;
    },
    updateBusyState(authState, {payload}: PayloadAction<boolean>) {
      authState.busy = payload;
    },
  },
});

export const {updateLoggedInState, updateProfile, updateBusyState} =
  slice.actions;

export const getAuthState = createSelector(
  (state: RootState) => state,
  ({auth}) => auth,
);

export default slice.reducer;
6rqinv9w

6rqinv9w1#

对于像你在这里做的事情,你真的不需要(也不应该使用)createSelector
而不是

export const getAuthState = createSelector(
  (state: RootState) => state,
  ({auth}) => auth,
);

你可以写

export const getAuthState = (state: RootState) => state.auth;

createSelector仅在选择器进行大量计算或创建新对象时才需要。
另外,你不应该做这样的事情

const {loggedIn, busy} = useSelector(getAuthState);

state.auth.profile.lastName(或者,实际上,state.auth中的任何其他内容)发生更改时,它也会重新呈现。
相反,做

const loggedIn = useSelector(rootState => getAuthState(rootState).loggedIn);
const busy = useSelector(rootState => getAuthState(rootState).busy);

相关问题