簡體   English   中英

為什么我的reducer在react / redux中返回一個空數組?

[英]Why is my reducer returning an empty array in react/redux?

在我的reducer中,它返回一個從api獲得的對象數組。 我在列表上做了一個console.log,我能夠看到數組,但是當我在反應類中訪問reducer時,它顯示為一個空數組,為什么會這樣呢? 在我的react文件中的render()函數內部,它確實打印了一些奇怪的原因,但我有一個函數,我正在嘗試使用reducer中的數據渲染單獨的div,並且數組顯示為空。

getList() {
        let arr = [];
        if(this.props.popular){
            arr = this.props.popular.map(item => {
                return (
                    <div key={item.id} className="movie">
                        <img
                            src={`https://image.tmdb.org/t/p/w300${item.poster_path}`}
                            //onClick={() => this.displayModal(item)}
                        />
                    </div>)
            })
        }
        // console.log(arr)
        // this.props.updateCurrentShowList(arr);
        return arr;
    }

我在下面的mapstatetoprops函數中使用this.props.popular。

import { FETCH_POPULAR, RESET_POPULAR } from "../Actions/types";

let initialList = [];

export default function(state = initialList, action){
    switch(action.type){
        case FETCH_POPULAR:
            //return action.payload || false;
            initialList = initialList.concat(...action.payload);
            //console.log(initialList);
            return initialList;

        case RESET_POPULAR:
            initialList = action.payload;
            return initialList;

        default:
            return state;
    }
}

這里初始列表打印並工作,然后我返回它。

這是我的mapStateToProps函數,我在我的其他文件中,我想要訪問該數組。 我在我的一個reducers文件中使用了combinereducers。

function mapStateToProps(state) {
    return {
        popular: state.popular
    };
}

當我在render()中執行此操作時,為什么this.props.popular會正確打印,但每當我在其他任何地方使用它時,它都沒有?

動作功能

export const fetchPopular = (searchTypeFormat, page) => async (dispatch) => {
    let url = `https://api.themoviedb.org/3/discover/${searchTypeFormat}?api_key=${APIKEY}&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}`;
    //console.log(url);
    const res = await axios.get(url);
    //console.log(res.data.results)
    dispatch({type: FETCH_POPULAR, payload: res.data.results});
};

我的商店創作

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reducers from './Reducers/index';
import reduxThunk from 'redux-thunk';


const store = createStore(reducers, {}, applyMiddleware(reduxThunk));

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root'));

我用這種方式組合了我的減速器

import { combineReducers } from 'redux';
import authReducer from './authReducer';
import popularReducer from './popularReducer';
import genreListReducer from './genreListReducer';
import searchByGenreReducer from './searchByGenreReducer';
import { reducer as formReducer } from 'redux-form';
import modalReducer from './modalReducer';
import detailsReducer from './moreDetailReducer';
import userDisplayList from './userDisplayList';

export default combineReducers({
    auth: authReducer,
    form: formReducer,
    popular: popularReducer,
    genreList: genreListReducer,
    searchByGenre: searchByGenreReducer,
    modalData: modalReducer,
    details: detailsReducer,
    displayList: userDisplayList
})

整個組成部分

import React, { Component } from 'react';
import { withRouter } from "react-router-dom";
import { connect } from 'react-redux';
import * as actions from '../Actions';

class SearchPopular extends Component {
    constructor(props) {
        super(props);

        this.state = {
            list: [],
            page: 1
        }
        this.getList = this.getList.bind(this);
    }
    componentWillMount() {
        //console.log(this.props.match.params.format)
        this.props.fetchPopular(this.props.match.params.format, this.state.page);
        console.log(this.props.popular)
        console.log(this.getList());
    }

    getList() {
        let arr = [];
        if(this.props.popular){
            arr = this.props.popular.map(item => {
                return (
                    <div key={item.id} className="movie">
                        <img
                            src={`https://image.tmdb.org/t/p/w300${item.poster_path}`}
                            //onClick={() => this.displayModal(item)}
                        />
                    </div>)
            })
        }
        //console.log(arr)
        // this.props.updateCurrentShowList(arr);
        return arr;
    }

render() {
    console.log(this.props.popular);
    return (
        <div>

        </div>
    );
}
}

function mapStateToProps(state) {
    return {
        popular: state.popular,
        updatedList: state.displayList
    };
}


export default withRouter(connect(mapStateToProps, actions)(SearchPopular));

您正在以錯誤的方式聲明更新。 你所做的是它最初將采用空數組,然后附加到其中。

case 'FETCH_POPULAR':
        return [...state, ...action.payload];

在你的減速機中嘗試這個。

****您的主要問題您正在嘗試獲取store.popular,但您不喜歡在商店中流行

const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const configureStore = () => {
    const store = createStore(
        combineReducers({
            popular: Your reducer here
        }),
        composeEnhancer(applyMiddleware(thunk))
    );
    return store;
}

****新的更新

我認為這是功能失去參考的問題。 這就是為什么我們在構造函數中使用this.getList.bind(this)所以當我們調用this.getList ,函數會獲取this的引用並可以使用它。 所以當你直接從任何其他函數調用它時,請使用this.getList.bind(this)

componentWillMount() {
        //console.log(this.props.match.params.format)
        this.props.fetchPopular(this.props.match.params.format, this.state.page);
        console.log(this.props.popular)
        console.log(this.getList.bind(this));
    }

不要在Redux redurs中改變變量! 你會得到許多奇怪的效果和競爭條件。 您希望始終從reducer返回新的新對象,除非在默認情況下沒有操作匹配,然后返回當前state

首先,不要用let定義你的初始狀態,然后在你的reducer中改變它,這是完全錯誤的。

其次,如果你想基於先前的狀態返回新的狀態,就像你的FETCH_POPULAR動作一樣,那么使用state參數(這就是它的用途)。

像這樣重寫,

export default function(state = [], action){
  switch(action.type){
    case FETCH_POPULAR:
      return [...state, ...action.payload];
    case RESET_POPULAR:
      return [];
    default:
      return state;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM