【问题标题】:Action not dispatching using react/ redux/ typescript未使用 react/redux/typescript 调度操作
【发布时间】:2020-05-30 03:01:35
【问题描述】:

我得到错误:

node_modules\react-native\Libraries\Core\ExceptionsManager.js:86 TypeError: Cannot read property 'videos' of undefined

此错误位于: 在 Connect(HomeHeader) (在 AppNavigator.tsx:116) 在 RCTView 中(在 View.js:35)

App.tsx:

const App = () => {
  return (
    <ImageBackground
      source={require('./assets/images/TC_background.jpg')}
      style={styles.container}>
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <AppNavigator
            ref={navigatorRef => {
              NavigationService.setTopLevelNavigator(navigatorRef);
            }}
          />
        </PersistGate>
      </Provider>
    </ImageBackground>
  );
};

AppNavigator.tsx:

const config = {
    contentOptions: {
        activeTintColor: '#e91e63',
        inactiveTintColor: '#ffffff',
        itemStyle: {
            flexDirection: 'row-reverse',
        },
    },
    drawerWidth: 200,
    drawerPosition: 'left',
    contentComponent: SideMenu,
    drawerBackgroundColor: '#00000020',
    cardStyle: {
        backgroundColor: 'transparent',
        opacity: 1,
    },
};

const withHeader = (
    screen: Function,
    routeName: string,
    Header: any,
): StackNavigator =>
    createStackNavigator(
        {
            [routeName]: {
                screen,
                navigationOptions: ({routeName, props}) => ({
                    header: props => <Header {...props} />,
                }),
            },
        },
        {
            initialRoute: 'Home',
            cardStyle: {
                backgroundColor: 'transparent',
                opacity: 1,
            },
            transitionConfig: () => ({
                containerStyle: {
                    backgroundColor: 'transparent',
                },
            }),
        },
    );

const routes = {
    ....
};

const NestedDrawer = createDrawerNavigator(routes, config);

const MainStack = createStackNavigator(
    {
        Home: {
            screen: HomeScreen,
            navigationOptions: ({ props }) => ({
                header: (props: any) => <HomeHeader {...props} />,
            }),
        },
        ...
    },
    {
        initialRoute: 'Home',
        cardStyle: {
            backgroundColor: 'transparent',
            opacity: 1,
        },
    },
);

export default createAppContainer(MainStack);

首页标题:

class HomeHeader extends Component {
    constructor(props) {
        super(props);
        this.state = { term: "", videos: [] };
        this.onSubmitEdit = this.onSubmitEdit.bind(this);
    }
    componentDidMount() {
        this.SearchFilterFunction("");
    }
    SearchFilterFunction(term) {
        const { filteredVideo } = this.props;
        filteredVideo(term);
    }

    onSubmitEdit() {
        const {
            navigation: { navigate },
            initSearch
        } = this.props;

        navigate("VideoEpisodes");
    }

    onPress(id) {
        const {
            navigation,
            initSearch,
            navigation: { dispatch }
        } = this.props;
        initSearch();

        const resetAction = StackActions.reset({
            index: 0,
            actions: [
                NavigationActions.navigate({
                    routeName: "VideoPlayer",
                    params: { id }
                })
            ]
        });
        dispatch(resetAction);
    }
    separator = () => <View style={styles.separator} />;
    render() {
        const {
            navigation,
            videos,
            search: { term },
            scene: {
                route: { routeName: title }
            }
        } = this.props;
        return (
            <..... />
        );
    }
}
const mapDispatchToProps = dispatch => ({
    filteredVideo: data => dispatch(filteredVideo(data)),
    initSearch: () => dispatch(initSearch())
});

const mapStateToProps = state => {
    return {
        videos: state.iaApp.videos,
        search: state.iaApp.search
    };
};

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(HomeHeader);

const styles = StyleSheet.create({
    container: {
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
        padding: 10,
        marginTop: Platform.OS === "ios" ? 20 : 0,
        paddingTop: Platform.OS === "ios" ? 20 : 10
    },
    title: {
        color: "#fff",
        fontSize: 18
    },
    separator: {
        borderBottomColor: "#d1d0d4",
        borderBottomWidth: 1
    }
});

主屏幕:

class HomeScreen extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
  }
  componentDidMount() {
    const {fetchData} = this.props;
    fetchData();
  }

  render() {
    const {videos} = this.props;

    return (
      <View style={styles.container}>
        <HomeMenu {...this.props} />
      </View>
    );
  }
}

const mapDispatchToProps = (dispatch: any) => ({
  fetchData: () => dispatch(fetchData()),
});
const mapStateToProps = (state: any) => {
  return {
    videos: state.IaApp.videos,
  };
};
export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(HomeScreen);

【问题讨论】:

    标签: reactjs typescript react-native redux


    【解决方案1】:

    尝试更改道具的名称,因为有时相同的道具和调度动作函数名称不起作用

    代替:

    const mapDispatchToProps = (dispatch: any) => ({
      fetchData: () => dispatch(fetchData()),
    });
    

    改为:

    const mapDispatchToProps = (dispatch: any) => ({
      _fetchData: () => dispatch(fetchData()),
    });
    

    并称之为:

     componentDidMount() {
        const {_fetchData} = this.props;
        _fetchData();
      }
    

    让我知道这是否有效

    【讨论】:

    • 另外,我正在学习打字稿,我需要运行 tsc 来编译 tsx 文件吗?我可以在我的模拟器上运行我的应用程序而无需编译,这让我很困惑。
    • 不,不需要编译,npx react-native run-xxx会自动处理
    猜你喜欢
    • 1970-01-01
    • 2019-10-23
    • 2017-11-09
    • 2018-10-23
    • 2018-12-10
    • 1970-01-01
    • 2018-07-16
    • 2016-09-23
    • 2020-08-18
    相关资源
    最近更新 更多