2

This is the smart component:

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

import Filter from '../Filter';
import Sort from '../Sort';

import { getItems, selectItem, reverseItems, findItems } from '../../actions/items';

import './app.css';

const App = ({filterList, sortList,  onGetItems, onFindItems, reverseItems, onSelectItem}) => {

onGetItems();

return (
    <div>
        <Filter items={filterList} findText={onFindItems} reverseItems={reverseItems} selectItem={onSelectItem} />
        <Sort items={sortList} selectItem={onSelectItem} />
    </div>
)}

function mapStateToProps(state) {
    return {
        filterList: state.items.filter(item => item.name.includes(state.filter.toLowerCase())),
        sortList: state.items,
    }
  }

function matchDispatchToProps(dispatch) {
    return bindActionCreators({
    onGetItems: getItems,
    onSelectItem: selectItem,
    onFindItems: findItems,
    reverseItems: reverseItems
}, dispatch)}

export default connect(mapStateToProps, matchDispatchToProps)(App);

and actions:

let items = [];

(function onGetItems() {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', '/items.json', false);
    xhr.send();
    if (xhr.status !== 200) {
        console.log(xhr.status + ': ' + xhr.statusText);
    } else {
        items = JSON.parse(xhr.responseText.toLowerCase());

        items.sort(function(a, b) {
            if (a.name > b.name) return 1;
            if (a.name < b.name) return -1;
            return 0;
        });
    }
})();

export const getItems = () => dispatch => {
    dispatch({ type: 'ADD_ITEMS', payload: items });
}

export const selectItem = (item)  => {
    console.log(item);
    return {
        type: "ITEM_SELECTED",
        payload: item
    }
};

export const reverseItems = (items)  => {
    console.log(items)
    return {
        type: "REVERSE_ITEMS",
        payload: items.reverse()
    }
};

export const findItems = (items)  => {
    return {
        type: "FIND_ITEMS",
        payload: items
    }
};

and 2 reducers:

const initialState = '';

export default function filter(state = initialState, action) {
    switch (action.type) {
        case 'FIND_ITEMS': return action.payload;
        default: return state
    }
}

const initialState = [];

export default function items(state = initialState, action) {
    switch (action.type) {
        case 'ADD_ITEMS': return action.payload;
        default: return state
    }
}

The action reverseItems reverses the array, but the problem is that it doesn't rewrite state because it's formed by another action.

I realize that it's a basic issue, but I can't get how to do that.

1
  • 3
    There are quite a few problems with your code, such as onGetItems is defined and immediately invoked, returned items are not stored in redux state, you are applying state transformation in your actions, etc. I suggest you check this (codementor.io/reactjs/tutorial/intro-to-react-redux-pros) or any other tutorial that can be found via google. Commented Mar 13, 2017 at 8:37

2 Answers 2

4

Replace your items.sort() statement with [...items].sort() which creates a new reference to the array and allows the re-rendering of the component. The sort function sorts the array using the same reference and does not cause a re-render.

Sign up to request clarification or add additional context in comments.

Comments

0

Try to use Redux Thunk for your async calls. You can dispatch an action, for example RECEIVED_ITEMS after your http request.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.