代码之家  ›  专栏  ›  技术社区  ›  Cacoon

TypeError:无法读取未定义的React Native Redux的属性“map”

  •  2
  • Cacoon  · 技术社区  · 7 年前

    我尝试创建一个reducer,遵循与git repos相同的逻辑

    /**
     * Created by kenji on 3/9/18.
     */
    /**
     * /stock?search=String
     * Searches Stock table, checking for given search value
     * and returns an array that contains that value
     * @action GET
     * @returns [array]
     * @type {string}
     */
    export const GET_STOCK_LIST = 'ReduxStarter/stock_list/LOAD';
    export const GET_STOCK_LIST_SUCCESS = 'ReduxStarter/stock_list/LOAD_SUCCESS';
    export const GET_STOCK_LIST_FAIL = 'ReduxStarter/stock_list/LOAD_FAILURE';
    
    /**
     * /stock/${id}
     * Gets an ID passed to it and returns an object if it exists
     * @action GET
     * @returns {object}
     * @type {string}
     */
    export const GET_STOCK = 'ReduxStarter/stock/LOAD';
    export const GET_STOCK_SUCCESS = 'ReduxStarter/stock/LOAD_SUCCESS';
    export const GET_STOCK_FAIL = 'ReduxStarter/stock/LOAD_FAIL';
    
    /**
     * /stock/${id}
     * Updates Stock by passing an object with new variables to update with
     * @action PUT
     * @returns {null}
     * @type {string}
     */
    export const PUT_STOCK = 'ReduxStarter/stock/CHANGE';
    export const PUT_STOCK_SUCCESS = 'ReduxStarter/stock/CHANGE_SUCCESS';
    export const PUT_STOCK_FAIL = 'ReduxStarter/stock/CHANGE_FAIL';
    
    /**
     * /stock/${id}/barcodes
     * Gets the barcodes of an a stock item if the ID is valid
     * @action: GET
     * @returns [array]
     * @type {string}
     */
    export const GET_BARCODES = 'ReduxStarter/stock/barcodes/LOAD';
    export const GET_BARCODES_SUCCESS = 'ReduxStarter/stock/barcodes/LOAD_SUCCESS';
    export const GET_BARCODES_FAIL = 'ReduxStarter/stock/barcodes/LOAD_FAIL';
    
    /**
     * /stock/barcode/${barcode}
     * Gets a stock item from the supplied barcode
     * @action: GET
     * @returns [array]
     * @type {string}
     */
    export const GET_STOCK_FROM_BARCODE = 'ReduxStarter/stock/barcode/LOAD';
    export const GET_STOCK_FROM_BARCODE_SUCCESS = 'ReduxStarter/stock/barcode/LOAD_SUCCESS';
    export const GET_STOCK_FROM_BARCODE_FAIL = 'ReduxStarter/stock/barcode/LOAD_FAIL';
    
    const initialState = {
        stockList: [],
        stock: {},
        result: {},
        barcodeList: [],
        stockFromBarcode: {},
    };
    
    export default function reducer(state = initialState, action) {
        switch(action.type) {
            case GET_STOCK_LIST:
                return { ...state, loadingStockList: true };
            case GET_STOCK_LIST_SUCCESS:
                return { ...state, loadingStockList: false, stockList: action.payload.data };
            case GET_STOCK_LIST_FAIL:
                return { ...state, loadingStockList: false, stockListError: 'Failed to retrieve stock list' };
            case GET_STOCK:
                return { ...state, loadingStock: true };
            case GET_STOCK_SUCCESS:
                return { ...state, loadingStock: false, stock: action.payload.data };
            case GET_STOCK_FAIL:
                return { ...state, loadingStock: false, stockError: 'Failed to retrieve stock list' };
            case PUT_STOCK:
                return { ...state, loadingStockUpdate: true };
            case PUT_STOCK_SUCCESS:
                return { ...state, loadingStockUpdate: false, result: action.payload.data };
            case PUT_STOCK_FAIL:
                return { ...state, loadingStockUpdate: false, stockUpdateError: 'Failed to update stock list' };
            case GET_BARCODES:
                return { ...state, loadingBarcodes: true };
            case GET_BARCODES_SUCCESS:
                return { ...state, loadingBarcodes: false, barcodeList: action.payload.data };
            case GET_BARCODES_FAIL:
                return { ...state, loadingBarcodes:false, barcodesError: 'Failed to load barcodes' };
            case GET_STOCK_FROM_BARCODE:
                return { ...state, loadingStockFromBarcode: true };
            case GET_STOCK_FROM_BARCODE_SUCCESS:
                return { ...state, loadingStockFromBarcode: false, stockFromBarcode: action.payload.data };
            case GET_STOCK_FROM_BARCODE_FAIL:
                return { ...state, loadingStockFromBarcode: false, stockFromBarcodeError: 'Failed to get stock item from barcode' };
            default:
                return state;
        }
    }
    
    export function listStockArray(searchQuery, pageSize = 50, pageNumber = 1) {
        return {
            type: GET_STOCK_LIST,
            payload: {
                request: {
                    url: `/stock?search=${searchQuery}&pageSize=${pageSize}&pageNumber=${pageNumber}`
                }
            }
        };
    }
    
    export function listStockItem(stockID) {
        return {
            type: GET_STOCK_LIST,
            payload: {
                request: {
                    url: `/stock/${stockID}`
                }
            }
        };
    }
    
    export function updateStock(stockID, data) {
        return {
            type: GET_STOCK_LIST,
            payload: {
                request: {
                    url: `/stock/${stockID}`,
                    method: `PUT`,
                    headers: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json'
                    },
                    data: data,
                }
            }
        };
    }
    
    export function listStockBarcodes(stockID) {
        return {
            type: GET_BARCODES,
            payload: {
                request: {
                    url: `/stock/${stockID}/barcodes`
                }
            }
        };
    }
    
    export function listStockFromBarcode(barcode) {
        return {
            type: GET_BARCODES,
            payload: {
                request: {
                    url: `/stock/barcode/${barcode}`
                }
            }
        };
    }
    

    现在我得到了标题中提到的错误:

    以下是应用程序中减速器的实现:

    import reducers from './redux/reducers/lots_reducer';
    import StockList from './components/StockList';
    
    const client = axios.create({
        baseURL: 'https://api.github.com',
        responseType: 'json'
    });
    
    const store = createStore(reducers, applyMiddleware(axiosMiddleware(client)));
    
    const Stack = createStackNavigator({
        StockList: {
            screen: StockList
        },
    });
    
    export default class App extends Component {
        render() {
            return (
                <Provider store={store}>
                    <View style={styles.container}>
                        <Stack/>
                    </View>
                </Provider>
            );
        }
    }
    

    最后是实际成分:

    import { connect } from 'react-redux';
    
    import { listStockArray } from '../redux/reducers/lots_reducer';
    
    class StockList extends Component {
    
        componentDidMount() {
            this.props.listStockArray('panadol');
        }
    
        renderItem = ({ stockList }) => (
            <TouchableOpacity
                style={styles.item}
                onPress={() => this.props.navigation.navigate(`Detail`, { name: stockList.StockID })}
            >
                <Text>{stockList.TradeName}</Text>
            </TouchableOpacity>
        );
    
        render() {
            const { stockList } = this.props;
            return (
                <FlatList
                    styles={styles.container}
                    data={stockList}
                    renderItem={this.renderItem}
                />
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1
        },
        item: {
            padding: 16,
            borderBottomWidth: 1,
            borderBottomColor: '#ccc'
        }
    });
    
    const mapStateToProps = state => {
        let storedRepositories = state.repos.map(repo => ({ key: (repo.id).toString(), ...repo }));
        return {
            repos: storedRepositories
        };
    };
    
    const mapDispatchToProps = {
        listStockArray
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(StockList);
    

    3 回复  |  直到 7 年前
        1
  •  1
  •   xadm    7 年前

    const mapStateToProps = state => {
        let storedRepositories = state.repos.map(repo => ({ key: (repo.id).toString(), ...repo }));
        return {
            repos: storedRepositories
        };
    };
    

    意味着你想要改变 id key 财产)州回购使用map函数并返回为 repos 使用中间变量 storedRepositories

    回购 数组。您还有一些其他数组处于状态(reducer中的initialState),但它们都不是 回购 .

    在reducer中,您将有效负载(获取的数据)存储在存储阵列中。

        case GET_STOCK_LIST_SUCCESS:
            return { ...state, loadingStockList: false, stockList: action.payload.data };
    

    stockList . 对于其他成功操作,您有其他数组名称。

    组件不必使用所有存储数据,您只能使用它感兴趣的部分—这就是 mapStateToProps 映射。你可以做的很简单

    const mapStateToProps = state => {
        return {
            stockList: state.stockList, 
            stock: state.stock
        };
    };
    

    这些值将作为 this.props.stockList this.props.stock .

        2
  •  0
  •   sagi    7 年前

    repos ,您想如何映射它?

    const initialState = {
      stockList: [],
      stock: {},
      result: {},
      barcodeList: [],
      stockFromBarcode: {},
      repos: []
    };
    

    或者,你指的是另一个领域。

        3
  •  0
  •   Revansiddh    7 年前

    map repo 不是数组。 有可能 回购 mapping 它(可能在赋值之前)。

    接近 我只是使用 Array.isArray()

    回购 字段作为空数组。基本上,这种错误发生在

    你试着用数组函数来表示非数组元素

    推荐文章