【问题标题】:React Native - Navigating by ID from api with Redux not workingReact Native - 在 Redux 不工作的情况下从 api 按 ID 导航
【发布时间】:2018-06-11 09:52:16
【问题描述】:

所以,我正在为我的应用程序使用 redux,到目前为止它还不错。但最近我碰上了一面墙,让我暂时无法编码。我正在尝试使用带有 redux 的数据库中每个项目的 ID 进行导航。假设我有一个“食物类别”页面,其中填充了我数据库中的项目,并且每个项目都有自己的 ID,使用这些 ID 我试图导航到第二个页面,即“菜肴页面”。如果用户单击一个类别,应用程序应显示该类别包含的菜肴。

到目前为止,我设法显示了类别,但我不知道如何应用导航。

每当我尝试添加一种我知道我遇到错误的导航时:

Error

state_error(**更新**)

你可以在我的代码中看到所有的细节。

这是我的代码:

App.js ( ** 编辑 ** )

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View
} from 'react-native';
import { StackNavigator } from 'react-navigation';

import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import Reducer from './app/redux/reducers/Reducer';

import AppContainer from './app/container/AppContainer';
import DishContainer from './app/container/DishContainer';
import Dishes from './app/component/Dishes';

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const store = createStoreWithMiddleware(Reducer);

export default class App extends Component{
  render() {
    return (
      <Provider store = { store }>
        <Root />
      </Provider>
    );
  }
}

const Root = StackNavigator ({
  AppContainer        : { screen: AppContainer },
  DishContainer       : { screen: DishContainer },
  Dishes              : { screen: Dishes },
})

Action.js

import {
    FETCHING_CATEGORY_REQUEST,
    FETCHING_CATEGORY_SUCCESS,
    FETCHING_CATEGORY_FAILURE,

    FETCHING_DISHES_REQUEST,
    FETCHING_DISHES_SUCCESS,
    FETCHING_DISHES_FAILURE,
} from "./types";
import axios from 'axios';
/* ---------------------- CATEGORY ---------------------------- */
export const fetchingCategoryRequest = () => ({
    type: FETCHING_CATEGORY_REQUEST
});
export const fetchingCategorySuccess = (json) => ({
    type: FETCHING_CATEGORY_SUCCESS,
    payload: json,
});
export const fetchingCategoryFailure = (error) => ({
    type: FETCHING_CATEGORY_FAILURE,
    payload: error
});
export const fetchCategory = () => {
    return (dispatch) => {
        axios.get('http://192.168.254.100:3308/categories/')
        .then(response => {
            dispatch({ type: FETCHING_CATEGORY_SUCCESS, payload: response.data })
        })
        .catch(error => console.log(error.response.data));
    }
}
/* ---------------------- DISHES ---------------------------- */
export const fetchingDishesRequest = () => ({
    type: FETCHING_DISHES_REQUEST
});
export const fetchingDishesSuccess = (json) => ({
    type: FETCHING_DISHES_SUCCESS,
    dish: json,
});
export const fetchingDishesFailure = (error) => ({
    type: FETCHING_DISHES_FAILURE,
    dish: error,
});
export const fetchDish = () => {
    return (dispatch) => {
        const { params } = this.props.navigation.state;
        axios.get('http://192.168.254.100:3308/categories/' + params.id)
        .then(response => {
            dispatch({ type: FETCHING_DISHES_SUCCESS, dish: response.data })
        })
        .catch(error => console.log(error.response.data));
    }
}

Reducer.js

const initialState = {
    isFetching: false,
    errorMessage: '',
    category: [],
    dishes: [],
};
const categoryReducer = (state = initialState, action) => {
    switch(action.type) {
        case FETCHING_CATEGORY_REQUEST:
        return {
            ...state,
            isFetching: true
        };
        case FETCHING_CATEGORY_FAILURE:
        return {
            ...state,
            isFetching: false,
            errorMessage: action.payload
        };
        case FETCHING_CATEGORY_SUCCESS:
        return {
            ...state,
            isFetching: false,
            category: action.payload
        };
/* --------------------- DISHES ------------------------- */
        case FETCHING_DISHES_REQUEST:
        return {
            ...state,
            isFetching: true
        };
        case FETCHING_DISHES_SUCCESS:
        return {
            ...state,
            isFetching: false,
            dishes: action.dish
        };
        case FETCHING_DISHES_FAILURE:
        return {
            ...state,
            isFetching: false,
            errorMessage: action.dish
        }
        default:
        return state;
    }
}
export default categoryReducer;

CategoryList.js

export default class CategoryList extends Component {
    _renderItem = ({ item }) => {
      const { cat_name } = item;
        return (
            <View style={styles.cardContainerStyle}>
                <View style={{ paddingRight: 5 }}>
                    <TouchableOpacity style = { styles.buttonContainer }>
                        <Text style={styles.cardTextStyle}
                        onPress = { () => this.props.navigation.navigate('Dishes', { id: item.cat_id })}>
                            {cat_name}
                        </Text>
                    </TouchableOpacity>
                </View>
            </View>
        );
    };
    render() {
        return (
            <FlatList
              style={{ flex: 1 }}
              data = {this.props.category}
              keyExtractor={(item, index) => index.toString()}
              renderItem={this._renderItem}
            />
        )
    }
}

AppContainer.js

import CategoryList from "../component/CategoryList";
import { fetchCategory } from '../redux/actions/Actions';
import { connect } from 'react-redux';

class AppContainer extends Component {
    componentDidMount() {
        this.props.fetchCategory();
    }
    render() {
        let content = <CategoryList category = { this.props.randomCategory.category }/>;
        if (this.props.randomCategory.isFetching) {
            content = <ActivityIndicator size="large"/>;
        }
        return <View style={styles.container}>{content}</View>;
    }
}
const mapStateToProps = state => {
    return {
        randomCategory: state
    };
}
export default connect(mapStateToProps, { fetchCategory })(AppContainer);

Dishes.js(这是我要从类别导航的地方)

export default class Dishes extends Component {
    _renderItem = ({ item }) => {
      const { cat_desc } = item;
        return (
            <View style={styles.cardContainerStyle}>
                <View style={{ paddingRight: 5 }}>
                    <TouchableOpacity>
                        <Text style={styles.cardTextStyle}>
                            {cat_desc}
                        </Text>
                    </TouchableOpacity>
                </View>
            </View>
        );
    };
    render() {
        const { params } = this.props.navigation.state;
        return (
            <FlatList
              style={{ flex: 1 }}
              data = {this.props.dishes}
              keyExtractor={(item, index) => index.toString()}
              renderItem={this._renderItem}
            />
        )
    }
}

DishContainer.js

import Dishes from "../component/Dishes";
import { fetchDish } from '../redux/actions/Actions';
import { connect } from 'react-redux';

class DishContainer extends Component {
    componentDidMount() {
        this.props.fetchDish();
    }
    render() {
        let content = <Dishes dishes = { this.props.randomDishes.dishes }/>;
        if (this.props.randomDishes.isFetching) {
            content = <ActivityIndicator size="large"/>;
        }
        return <View style={styles.container}>{content}</View>;
    }
}
const mapStateToProps = state => {
    return {
        randomDishes: state
    };
}

编辑:某些参数不起作用或 props.navigation.navigate 没有从我的 api 调用项目的 id。我不确定,请帮助我。

【问题讨论】:

    标签: javascript reactjs react-native redux react-navigation


    【解决方案1】:

    像下面这样编辑你的 AppContainer.js:

    import CategoryList from "../component/CategoryList";
    import { fetchCategory } from '../redux/actions/Actions';
    import { connect } from 'react-redux';
    
    class AppContainer extends Component {
    componentDidMount() {
        this.props.fetchCategory();
    }
    render() {
        let content = <CategoryList 
               navigation = {this.props.navigation}
               category = {this.props.randomCategory.category}/>;
        if (this.props.randomCategory.isFetching) {
            content = <ActivityIndicator size="large"/>;
        }
        return <View style={styles.container}>{content}</View>;
    }
    }
    const mapStateToProps = state => {
    return {
        randomCategory: state
    };
    }
    export default connect(mapStateToProps, { fetchCategory })(AppContainer);
    

    问题是CategoryList无法获取父组件的navigation props(AppCountainer),所以你必须将navigation作为props传递。

    【讨论】:

    • 谢谢先生,您的代码删除了错误。但是,它不会导航到 soconde 屏幕。
    • 您是否在导航路线中定义了Dishes
    • 我现在只在我的 App.js 中定义 Dishes。它是空白的,为什么会这样?我会更新我的问题让您查看我的 App.js
    • 你使用的是哪个 ReactNavigation 版本?
    • “react-native”:“0.55.4”,先生。先生,您不认为这与我的 DishConainer 有关吗?因为我在那里导入了我的 Dishes.js。
    猜你喜欢
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-14
    • 2018-10-16
    相关资源
    最近更新 更多