Постоянное значение не повлияет на код в цепочке - PullRequest
0 голосов
/ 27 декабря 2018

Это действие filterAction, которое передает значение постоянному редуктору.Это действие вызывается с dispatch() в раскрывающемся списке компонента.

import { SORT_BY_TITLE, SORT_BY_RELEASED_AT } from './types';

// sort by title
export const sortByTitle = () => ({
  type: SORT_BY_TITLE
});

// sort by released at
export const sortByReleasedAt = () => ({
  type: SORT_BY_RELEASED_AT
});

Соответствующее filterReducer

import { SORT_BY_TITLE, SORT_BY_RELEASED_AT } from '../actions/types';

const initialState = {
  sortBy: 'title'
};

export default function(state = initialState, action) {
  switch(action.type) {
    case SORT_BY_TITLE:
      return {
        ...state,
        sortBy: 'title'
      };
    case SORT_BY_RELEASED_AT:
      return {
        ...state,
        sortBy: 'releasedAt'
      };
    default:
      return state;
  }
};

Значение filterReducer - это значение, которое сохраняется в основнойкомбинированный редуктор.

export default combineReducers({
  books: booksReducer,
  book: bookReducer,
  form: addBookFormReducer,
  filter: filterReducer
});

Значение приложения store

import { createStore, applyMiddleware } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

const middleware = [thunk];

const persistConfig = {
    key: 'root',
    storage,
    whitelist: ['filter']
};

const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = createStore(persistedReducer, {}, applyMiddleware(...middleware));
export const persistor = persistStore(store);

Значение, сохраненное в filter части главного редуктора, отображается в раскрывающихся списках, при вызове которых filterAction с dispatch().

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

import {
    GET_BOOKS,
    BOOKS_LOADING,
    DELETE_BOOK,
    SORT_BY_TITLE,
    SORT_BY_RELEASED_AT
} from '../actions/types';

const initialState = {
  books: [],
  loading: false
};

const booksReducer = (state = initialState, action) => {
  switch(action.type) {
    case BOOKS_LOADING:
      return {
        ...state,
        loading: true
      };
    case GET_BOOKS:
      return {
        ...state,
        books: action.payload,
        loading: false
      };
    case DELETE_BOOK:
      return {
        books: [...state.books.filter(book => book._id !== action.payload.id)]
      };
        case SORT_BY_TITLE:
            return {
                ...state,
                books: [...state.books.sort((a, b) => a.title < b.title ? -1 : 1 )]
            };
        case SORT_BY_RELEASED_AT:
            return {
                ...state,
                books: [...state.books.sort((a, b) => a.releasedAt < b.releasedAt ? -1 : 1 )]
            };
    default:
      return state;
  }
};

export default booksReducer;

Часть filter основного редуктора сохраняется нормально при перезагрузке страницы, однако список books отображается с сортировкой заголовка по умолчанию.

Как заставить приложение сохранять сортировку при перезагрузке страницы?Полное репо на https://github.com/ElAnonimo/booklister

1 Ответ

0 голосов
/ 29 декабря 2018

При загрузке действия BookList возврат действия getBooks() сбрасывает список отсортированных книг к сортировке по умолчанию, чтобы было легче сохранить только значение filter из store, а затем сортировать список books на каждомзагрузка компонента BookList.

Изменения были сделаны

до booksReducer

import {
    GET_BOOKS,
    BOOKS_LOADING,
    DELETE_BOOK
} from '../actions/types';

const initialState = {
  books: [],
    loading: false
};

const booksReducer = (state = initialState, action) => {
  switch(action.type) {
    case BOOKS_LOADING:
      return {
        ...state,
        loading: true
      };
    case GET_BOOKS:
      return {
        ...state,
        books: action.payload,
        loading: false
      };
    case DELETE_BOOK:
      return {
        books: [...state.books.filter(book => book._id !== action.payload.id)]
      };
    default:
      return state;
  }
};

export default booksReducer;

до BookList

class BookList extends Component {
  componentDidMount() {
    this.props.getBooks();
  }

  applySorting(books) {
    const sortBy = this.props.filter.sortBy;

    if (!sortBy) {
        return books;
        }

        return books.sort((a, b) => a[sortBy] < b[sortBy] ? -1 : 1);
    }

  render() {
    const { books, loading } = this.props.books;

    let booksContent;

    if (!books || loading) {
      booksContent = <Spinner />;
    } else {
      if (books.length > 0) {
        booksContent = this.applySorting(books).map(book => <BookItem book={book} key={book._id} />);
      } else {
        booksContent = <h4>No books found</h4>;
      }
    }
...
...
...