Список Рецептов Обертывание


Я сделал простой реагировать + приложение Redux, который позволяет вам добавлять и удалять рецептов список.

Здесь представлены рассказы пользователей приложения выполняет:

Рассказ пользователя: я могу создавать рецепты, которые имеют названия и ингредиенты.

Рассказ пользователя: я могу посмотреть индекс, где имена все рецепты видны.

Рассказ пользователя: я могу нажать на любую из этих рецептов, чтобы просмотреть его.

Рассказ пользователя: я могу удалить эти рецепты.

История пользователя: все новые рецепты я добавляю сохраняются в локальном хранилище моего браузера. Если я обновить страницу, эти рецепты будут.

Код:

import React from 'react'
import ReactDOM from 'react-dom'
import { connect } from 'react-redux'
import { createStore } from 'redux'

const ADD_RECIPE = 'ADD_RECIPE'
const SHOW_RECIPE = 'SHOW_RECIPE'
const EDIT_RECIPE = 'EDIT_RECIPE'
const UPDATE_ACTIVE_NAME = 'UPDATE_ACTIVE_NAME'
const UPDATE_ACTIVE_INGREDIENTS = 'UPDATE_ACTIVE_INGREDIENTS'
const TOGGLE_ACTIVE_ID = 'TOGGLE_ACTIVE_ID'
const DELETE_RECIPE = 'DELETE_RECIPE'

const initialState = {
  activeName: '',
  activeIngredients: '',
  activeId: '',
  recipes: [
    {
      id: 1,
      name: 'Pizza',
      ingredients: 'Dough, tomato, cheese, salt, pepper, olives, mushrooms, ham.'
    },
    {
      id: 2,
      name: 'Sherpherd\'s Pie',
      ingredients: 'Potato, lamb'
    },
    {
      id: 3,
      name: 'Huel Shake',
      ingredients: 'Milk, huel'
    }
  ]
}

// action creators
const saveStoreRecipesToLocalStorage = (state) => {
  localStorage.setItem('state', JSON.stringify(
    {...state, activeId: ""}
  ));
}

const getStoreRecipesFromLocalStorage = () => {
  const state = JSON.parse(localStorage.getItem('state'))
  return state.recipes.length && state
}

const addRecipe = (id, name, ingredients) => {
  return {
    type: ADD_RECIPE,
    payload: {
      id,
      name,
      ingredients
    }
  }
}

const updateActiveName = payload => {
  return {
    type: UPDATE_ACTIVE_NAME,
    payload
  }
}

const updateActiveIngredients = payload => {
  return {
    type: UPDATE_ACTIVE_INGREDIENTS,
    payload
  }
}

const toggleActiveId = id => {
  return {
    type: TOGGLE_ACTIVE_ID,
    payload: id
  }
}

const deleteRecipe = id => {
  return {
    type: DELETE_RECIPE,
    payload: id
  }
}

// reducer
function recipes (state = getStoreRecipesFromLocalStorage() || initialState, action) {
  console.warn('action:', action)
  switch (action.type) {
    case TOGGLE_ACTIVE_ID:
      return {...state, activeId: action.payload}
    case UPDATE_ACTIVE_NAME:
      return {...state, activeName: action.payload}
    case UPDATE_ACTIVE_INGREDIENTS:
      return {...state, activeIngredients: action.payload}
    case ADD_RECIPE:
      return {...state, recipes: [...state.recipes, action.payload]}
    case DELETE_RECIPE:
      return {...state, recipes: state.recipes.filter(recipe => recipe.id !== action.payload)}
    case EDIT_RECIPE:
      return
    default:
      return state
  }
}

const Recipes = (props) => {
  getStoreRecipesFromLocalStorage()
  const {addRecipe, updateActiveIngredients, updateActiveName, toggleActiveId, deleteRecipe, state} = props
  const id = new Date().getTime() / 1000
  return (
    <div style={{width: 320}}>
      <form onSubmit={e => {
        e.preventDefault()
        addRecipe(id, state.activeName, state.activeIngredients)
      }}>
        <input
          type="text"
          placeholder="Name"
          value={state.activeName}
          onChange={(e) => updateActiveName(e.target.value)}
        />
        <input
          placeholder="Ingredients"
          value={state.activeIngredients}
          onChange={e => updateActiveIngredients(e.target.value)}
        />
        <button type="submit">Add Recipe</button>
      </form>
      {state.recipes.map(item => <ul key={item.name}>
        <div style={{display: 'flex', justifyContent: 'space-between'}}>
          <li onClick={() => toggleActiveId(item.id)}>
            <div>{item.name}</div>
            {state.activeId === item.id && <div>{item.ingredients}</div>}
          </li>
          <div style={{color: 'red'}} onClick={() => deleteRecipe(item.id)}>&times;</div>
        </div>
      </ul>)}

    </div>
  )
}

const mapStateToProps = (state) => {
  return {
    state
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    addRecipe: (id, name, ingredients) => {
      if (name && ingredients) {
        dispatch(addRecipe(id, name, ingredients))
        dispatch(updateActiveName(''))
        dispatch(updateActiveIngredients(''))
        saveStoreRecipesToLocalStorage(ownProps.store.getState())
      }
    },
    updateActiveName: name => dispatch(updateActiveName(name)),
    updateActiveIngredients: ingredients => dispatch(updateActiveIngredients(ingredients)),
    toggleActiveId: id => dispatch(toggleActiveId(id)),
    deleteRecipe: id => {
      dispatch(deleteRecipe(id))
      saveStoreRecipesToLocalStorage(ownProps.store.getState())
    }
  }
}

const App = connect(
  mapStateToProps,
  mapDispatchToProps
)(Recipes)

const store = createStore(recipes, window.__REDUX_DEVTOOLS_EXTENSION__())
const render = () => ReactDOM.render(<App store={store}/>, document.getElementById('root'))
store.subscribe(render)
render()

Я хотел, как лучше структурировать приложение, разделив этот файл на отдельные файлы, но ради этого вопроса я держал это в одном файле.

Демо (адаптирован для Сайт CodePen без хранилище localStorage особенности): https://codepen.io/alanbuchanan/pen/LQWKBZ

Сделав это небольшое приложение, принес некоторые вопросы у меня о Redux:

  1. У меня есть updateActiveName и updateActiveIngredients функция, потому что есть только эти два поля, которые добавляются к форме. Было бы лучше, вместо того, чтобы использовать updateActiveObject и при любом поле изменяет? Я вижу в этом выгоду, когда другие поля добавляются, но менее эффективно, потому что я буду работает функция onChange для нескольких полей, которые не меняются.

  2. Имена моих действий создателей, редукторы и функции внутри mapDispatchToProps обычно то же самое. Например UPDATE_ACTIVE_INGREDIENTS, updateActiveIngredients действия Творца и updateActiveIngredients функция. Есть ли лучший подход к этому?

  3. В addRecipe функция внутри mapDispatchToPropsЯ проверка name и ingredients значения. Это должно идти внутри этой функции, или где-то еще?

  4. В addRecipe функция внутри mapDispatchToPropsЯ посылать много действий. Это правильно практиковать?

Любой другой обратной связи для совершенствования своего Redux является самым желанным.



204
1
задан 10 февраля 2018 в 07:02 Источник Поделиться
Комментарии
1 ответ

Я только начал работать с React/Redux на себя, но вот мои мысли.


  1. В моей системе я спасаю значений формы к местной составляющей государства до тех пор, пока форма сохраняется. У меня есть один метод обработчика onChange, который проверяет, что форма поля и затем выполнении функция setState.

  2. Это я что-то тоже найти с помощью React/Redux на - много шаблонного и повторения, чтобы обновить несколько штук данных... похож на себя, я имею типов действий / создатели боевик / вызовов API / редукторы методов / компонент всех с очень похожими названиями. Я думаю, что это просто так оно и есть. Я также с нетерпением, чтобы включить обертывание-сага в нашем коде, так что потенциально означает еще больше одноименных методов.

  3. Я использую петрушку для форма проверки, так что код обрабатывается библиотека. Если мне действительно нужно, чтобы сделать дальнейшие проверки, я бы сделал это в onChange, после чего перед изменением местной составляющей государства.

  4. У вас все в одном компоненте на данный момент для просмотра рецептов и добавления рецептов. Я бы разделил их на отдельные компоненты и затем, как только вы закончите с сохранением новый рецепт, еще раз представить список. Ваше приложение очень хотел, чтобы сделать список приложение, взглянуть на примеры.

Если бы не скорость реакции, перевождь, я, вероятно, не беспокоить!

Вот пример, чтобы сделать приложение, которое имеет аналогичную структуру моего приложения (который, я надеюсь, хорошо структурированный лол).
https://github.com/reactjs/redux/tree/master/examples/todomvc

0
ответ дан 11 февраля 2018 в 12:02 Источник Поделиться