繁体   English   中英

如何修复 TypeError:navigation.setOptions 不是 function

[英]How to fix TypeError: navigation.setOptions is not a function

我正在尝试用我的应用程序开玩笑地实现本机测试库。

现在我的组件导航有问题。

当我运行测试时,我遇到了一个错误:

TypeError: navigation.setOptions is not a function

这是我的组件:

const initialState: StateTypes = {
  toShowAsGridLayout: false,
  isLoadingMoreContacts: false
};

export const Main: FC<Props> = ({ navigation }) => {
  const dispatch = useDispatch();
  const { data } = useSelector((state: RootState) => state.appReducer);

  const [state, setState] = useState<StateTypes>(initialState);

  useLayoutEffect(() => {
    navigation.setOptions({
      title: state.isLoadingMoreContacts ? strings.LOADING : strings.ALL_CONTACTS + ' - ' + data.length,
      headerRight: () => (
        <TouchableOpacity style={styles.changeLayoutButton} onPress={changeLayout}>
          <Text style={styles.changeLayoutText}>{state.toShowAsGridLayout ? strings.LIST : strings.GRID}</Text>
        </TouchableOpacity>
      )
    });
  }, [state.isLoadingMoreContacts, state.toShowAsGridLayout])

  return (
    <View style={styles.container}>
      {renderLayout()}
    </View>
  );
};

这是一个路由器:

const SplashStack = createStackNavigator();
const MainStack = createStackNavigator();

export const RootNavigator = () => {
  const { isDataLoading } = useSelector((state: RootState) => state.appReducer);

  return (
    isDataLoading
      ? <SplashStack.Navigator>
        <SplashStack.Screen name={'SplashStack'} component={Splash} />
      </SplashStack.Navigator>
      : <MainStack.Navigator>
        <MainStack.Screen name={'Main'} component={Main} />
        <MainStack.Screen name={'ContactDetails'} component={ContactDetails} />
      </MainStack.Navigator>
  );
};

还有一个测试本身:

import React from 'react';

import { render } from '@testing-library/react-native';
import { Main } from '../Main';
import * as redux from 'react-redux';
import strings from '../../constants/strings';
import mocks from '../../mocks';

describe('dispatch mock', () => {
  it('should dispatch mock', () => {
    const useDispatchSpy = jest.spyOn(redux, 'useDispatch');
    const useSelectorSpy = jest.spyOn(redux, 'useSelector');
    const mockDispatchFn = jest.fn();
    useDispatchSpy.mockReturnValue(mockDispatchFn);
    useSelectorSpy.mockReturnValue({ data: mocks });

    const { getByText } = render(<Main navigation={({})} />);
    getByText(strings.ALL_CONTACTS);
  });
});

我该如何解决这个错误? 我应该将什么传递给导航道具:

const { getByText } = render(<Main navigation={({})} />);

您需要使用setOptions方法传递对象。

const { getByText } = render(<Main navigation={
  {
    setOptions: (props: { title: string, headerRight: React.FC }) => void
  }
} />);

这个答案可能是相关的

出于我的目的,解决方案非常简单,我只是添加了?. setOptions结束时

useLayoutEffect(() => {
    navigation.setOptions?.({ // <--- CHANGED HERE 

      title: state.isLoadingMoreContacts ? strings.LOADING : strings.ALL_CONTACTS + ' - ' + data.length,
      headerRight: () => (
        <TouchableOpacity style={styles.changeLayoutButton} onPress={changeLayout}>
          <Text style={styles.changeLayoutText}>{state.toShowAsGridLayout ? strings.LIST : strings.GRID}</Text>
        </TouchableOpacity>
      )
    });
  }, [state.isLoadingMoreContacts, state.toShowAsGridLayout])

我也面临同样的问题。 通过以下代码更改,我解决了我的问题。

有关更多信息,请查看此答案

    const createTestProps = (props: Object) => ({
          navigation: {
            navigate: jest.fn(),
            setOptions: jest.fn()
          },
          ...props
        });
    const props = createTestProps({});    
    const { toJSON } = render(<MainScreen {...props} />); 

在此处输入图像描述

您必须模拟您在屏幕中使用的属性和 function 必须像上面一样模拟。 有关更多信息,请查看此答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM