M
M
mishapsv2015-09-08 12:16:32
React
mishapsv, 2015-09-08 12:16:32

What is the correct way to display products with the possibility of deletion in Redux?

I asked a similar, but general question, then I didn’t understand, because. slow-witted. Now a more specific example.
(Based on an example of a to-do list from the documentation)
Task:
display several product cards with the ability to delete them when you click on the button (i.e. press the button on the product card => this card disappears).
Action

/*constants\ActionTypes.js*/
export const DELETE_TODO = 'DELETE_TODO';

Action Creator
/*actions\todos.js*/
import * as types from '../constants/ActionTypes';

export function deleteTodo(id) {
  return { type: types.DELETE_TODO, id };
}

Reducer
/*reducers\todos.js*/
import {DELETE_TODO} from '../constants/ActionTypes';

const initialState = [{
  {/*объект с карточками товаров должен быть здесь?*/}
}];

export default function todos(state = initialState, action) {
  switch (action.type) {

  case DELETE_TODO:
    return state.filter(todo =>
      todo.id !== action.id
    );

  default:
    return state;
  }
}

/*reducers\index.js*/
import { combineReducers } from 'redux';
import todos from './todos';

const rootReducer = combineReducers({
  todos
});

export default rootReducer;

"Stupid" product card component:
/*components\TodoItem.js*/
import React, { Component, PropTypes } from 'react';

class Bbutton extends Component {
  render() {
    const {todo, completeTodo, deleteTodo} = this.props;
    return (
      <p><a href='#'
className="btn btn-primary" role="button">Подробнее</a></p>
    )};
  }

class TodoItem extends Component {
  constructor(props, context) {
    super(props, context);
  }

  render() {
    const {todo, deleteTodo, src, title, descr, id} = this.props;
    return (
      <div className="col-sm-4 col-md-4">
              <div className="thumbnail">
                  <img src={src} height="100" alt="..."/>
                  <div className="caption">
                      <h3>{title}</h3>
                      <p>{descr}</p>
                      <Bbutton onClick={() => deleteTodo(id)} />
                  </div>
              </div>
          </div>
    );
  }
}

TodoItem.propTypes = {
  deleteTodo: PropTypes.func.isRequired,
};

export default TodoItem;

"Stupid" component, where map will generate product cards
/*components\MainSection.js*/
import React, { Component, PropTypes } from 'react';
import TodoItem from './TodoItem';

/* Этот объект должен быть здесь или в редьюсере? Или подключаться и там и там?
var pictures = [
  {descr: 'Стильный и модный', title: 'Iphone 6', id: 0, src: 'http://content2.onliner.by/catalog/device/header/5c89a202887278d66e83e9ea119a537d.jpg'},
  {descr: 'Стильный и модный 2', title: 'Iphone 5s', id: 1, src: 'http://content2.onliner.by/catalog/device/header/f16849c646ec7b06d7ceaa62c1a1b883.jpg'},
  {descr: 'Стильный и модный 3', title: 'Iphone 5', id: 2, src: 'http://content2.onliner.by/catalog/device/header/98b010c3ae263120c548aa3856fefc2f.jpg'},
];
*/
class MainSection extends Component {
  constructor(props, context) {
    super(props, context);
  }

  render() {
    const { todos, actions } = this.props;
    return (
      <section className="main">
        <ul className="todo-list">
          {pictures.map(todo =>
            <TodoItem key={todo.id} todo={todo} {...actions} />
          )}
        </ul>
      </section>
    );
  }
}

MainSection.propTypes = {
  todos: PropTypes.array.isRequired,
  actions: PropTypes.object.isRequired
};

export default MainSection;

The only "smart" (not like me) component
/*containers\App.js*/
import React, { Component, PropTypes } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import MainSection from '../components/MainSection';
import * as TodoActions from '../actions/todos';

class App extends Component {
  render() {
    const { todos, dispatch } = this.props;
    const actions = bindActionCreators(TodoActions, dispatch);

    return (
      <div>
        <MainSection todos={todos} actions={actions} />
      </div>
    );
  }
}

App.propTypes = {
  todos: PropTypes.array.isRequired,
  dispatch: PropTypes.func.isRequired
};

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

export default connect(mapStateToProps)(App);

Store
/*store\configureStore.js*/
import { createStore } from 'redux';
import rootReducer from '../reducers';

export default function configureStore(initialState) {
  const store = createStore(rootReducer, initialState);

  if (module.hot) {
    // Enable Webpack hot module replacement for reducers
    module.hot.accept('../reducers', () => {
      const nextReducer = require('../reducers');
      store.replaceReducer(nextReducer);
    });
  }
  return store;
}

Binding a smart component to Redax
/*index.js*/
import 'babel-core/polyfill';
import React from 'react';
import { Provider } from 'react-redux';
import App from './containers/App';
import configureStore from './store/configureStore';
import 'todomvc-app-css/index.css';

const store = configureStore();

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

How to display product cards and how to delete when clicking on the button?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question