Почему состояние, возвращаемое из моего редуктора, является пустым объектом ?? (React-Redux) - PullRequest
0 голосов
/ 07 октября 2018

У меня проблема с моим редукторным редуктором, он не возвращает ожидаемое состояние после отправки действия «FETCH_BOOKS», он возвращает пустой объект вместо объекта состояния, то есть книги, которые выбираются по запросу AJAX, редуктор возвращает правильныйданные при сохранении моего состояния в массиве вместо объекта, это так запутанно, почему это происходит ??

Это мои компоненты

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import * as BooksAPI from './BooksAPI';
import registerServiceWorker from './registerServiceWorker';
import { createStore, applyMiddleware } from 'redux';
import { bookReducer } from './reducers/BookReducer';
import thunk from 'redux-thunk';
import {BrowserRouter as Router} from 'react-router-dom';

const middleware = [thunk];
const initialState = {};
const store = createStore(bookReducer, initialState, applyMiddleware(...middleware));

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

Приложение.js

import React, { Component } from 'react';
import { connect } from 'react-redux'
import BookShelf from './components/BookShelf'
import AllShelves from './components/AllShelves'
import Header from './components/Header';
import SearchPage from './components/SearchPage';
import * as BooksAPI from './BooksAPI';
import { Route, withRouter } from 'react-router-dom';
import './App.css';

class App extends Component {  

  componentWillMount() {
    this.props.fetchBooks();
  }

  render() {
    console.log(this.props.books)
    return (
      <div className="App">
        <Header />
        <Route exact path="/" component={AllShelves} />         
        <Route  path="/search" component={SearchPage} />
      </div>
    );
  }
}


const mapStateToProps = (state) => {
    return {
      books: state.books
    }
}

const mapDispatchToProps = (dispatch) => {
  return {
    fetchBooks: () => {
       BooksAPI.getAll().then(books => dispatch({
         type: 'FETCH_BOOKS',
         books
       }))
    },

  }
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App))

редуктор, который не работает

import { FETCH_BOOKS } from '../actions/Types.js';

import * as BooksAPI from '../BooksAPI'

const initialState = {
  books: [],
  query: ''
}

 export const bookReducer = (state = initialState, action) => {
   switch(action.type) {
     case 'FETCH_BOOKS':
       return {
         ...state,   
         books: action.books,
       }
     default: 
       return state;
   }
}

Редуктор, который работает

 export const bookReducer = (state = [], action) => {
   switch(action.type) {
     case 'FETCH_BOOKS':
       return action.books
     default: 
       return state;
   }
}

Так почему сохранение состояния в объекте не работает ион отлично работает с массивом, я не хочу хранить свое состояние в массиве, так как книги - это не единственные данные, которыми мне нужно управлять в моем состоянии !!!

Ответы [ 3 ]

0 голосов
/ 07 октября 2018

После того, как любое действие отправлено, вы должны вернуть новое состояние в хранилище, поэтому вам нужно вернуть новый объект состояния, для которого вы должны получить состояние сейчас, изменить книги и вернуть новое состояние, так что следующий код делает это

export const bookReducer = (state = initialState, action) => {
switch(action.type) {
 case 'FETCH_BOOKS':
   return {
     ...state,   
     books: action.books,
   }
 default: 
   return state;
}
}

но из другого редуктора вы возвращаете только массив книг, полученный из действия, которое является неправильным способом сделать это

0 голосов
/ 07 октября 2018

Я проверил все ваши коды и думаю, что проблема, возможно, связана с настройкой магазина приставок:

const initialState = {};
const store = createStore(bookReducer, initialState, applyMiddleware(...middleware));

Я предлагаю удалить initialState:

const initialState = {};    // remove this line cuz we don't need it
const store = createStore(bookReducer, applyMiddleware(...middleware)); //fixed like this

Кроме того,Я думаю, что вы должны получить свои книги в componentDidMount() хуке жизненного цикла вместо componentWillMount(), например:

componentDidMount() {
  this.props.fetchBooks();
}
0 голосов
/ 07 октября 2018

Во втором примере вы выбираете значение в редукторе как action.books , вместо этого оно должно быть action.payload , потому что это ключ, отправленный в действии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...