#reactjs #redux
#reactjs #redux
Вопрос:
Я пытаюсь вызвать создателя действия добавить продукт из компонента продукта формы. Я не понимаю, где я ошибаюсь. Может кто-нибудь, пожалуйста, помочь мне решить эту проблему? Я новичок в redux, так как я могу добиться решения, чтобы при заполнении формы продукт должен быть добавлен и вызывается создатель действия.
Вот код :
FormProduct.js
import { makeStyles, TextField, Grid } from '@material-ui/core'
import React, { useState, useEffect } from 'react'
import { useForm, Form } from '../useForm'
import Input from '../../components/controls/Input'
import Select from '../controls/Select'
import * as productService from '../../services/productService'
import DatePicker from '../controls/DatePicker'
import Button from '../controls/Button'
const initialValues = {
id: 0,
name: '',
description: '',
quantity: '',
price: '',
dop: new Date(),
category: ''
}
const FormProduct = (props) => {
const validate = (fieldValues = values) => {
let errors = { }
if ('name' in fieldValues)
errors.name = values.name ? '' : 'This field is required'
if ('description' in fieldValues)
errors.description = values.description ? '' : 'This field is required'
if ('quantity' in fieldValues)
errors.quantity = values.quantity ? '' : 'This field is required'
if ('price' in fieldValues)
errors.price = values.price ? '' : 'This field is required'
if ('category' in fieldValues)
errors.category = values.category.length != 0 ? '' : 'This field is required'
setErrors({
...errors
})
if (fieldValues == values)
return Object.values(errors).every((formValues) => formValues == '')
}
const { values, setValues, handleChange, errors, setErrors, resetForm } = useForm(initialValues, true, validate)
const handleSubmit = (e) => {
console.log('handleSubmit',props)
e.preventDefault()
if (validate())
{
props.onSubmit(values)
}
}
return (
<Form onSubmit={handleSubmit}>
<Grid container>
<Grid item>
<Input
name='name'
value={values.name}
label='Name'
onChange={handleChange}
error={errors.name} />
<Input
label='Description'
name='description'
value={values.description}
onChange={handleChange}
error={errors.description} />
<Input
label='Quantity'
name='quantity'
value={values.quantity}
onChange={handleChange}
error={errors.quantity} />
<Input
label='Price'
name='price'
value={values.price}
onChange={handleChange}
error={errors.price} />
<DatePicker
name='dop'
label='Date Of Purchase'
value={values.dop}
onChange={handleChange} />
<Select
name='category'
label='Category'
value={values.category}
onChange={handleChange}
options={productService.getProductCollection()}
error={errors.category} />
<div>
<Button variant='contained'
color='primary'
size='large'
text='Submit'
type='submit' />
</div>
</Grid>
</Grid>
</Form>
)
}
export default FormProduct
AddProduct.js
import React from 'react'
import {connect} from 'react-redux'
import {addProduct} from 'redux'
import FormProduct from './FormProduct'
const AddProduct = (props) => {
const onSubmit=(product)=>{
props.addProduct(product)
}
return (
<div>
<FormProduct onSubmit={onSubmit}/>
</div>
)
}
export default connect(null,{addProduct:addProduct})(AddProduct)
actions.js
import products from '../apis/products'
import {ADD_PRODUCT,LIST_ALL_PRODUCTS} from './types'
import { v4 as uuid } from 'uuid'
export const addProduct=(productDetails)=>{
return async (dispatch)=>{
const productId=uuid()
const response=await products.post('/products',{...productDetails,productId})
dispatch({
type:ADD_PRODUCT,
payload:response.data
})
}
}
reducers.js
import {ADD_PRODUCT} from '../actions/types'
import _ from 'lodash'
const productsReducer=(state={},action)=>{
switch(action.type){
case ADD_PRODUCT:
return {...state,[action.payload.id]:action.payload}
default:
return state
}
}
export default productsReducer
Комментарии:
1. Я думаю, что в данном случае вы импортируете свое действие не из,
redux
а из файла, который вы его определилиactions.js
. Вы можете попробовать это?2. Я импортировал добавить продукт из файла actions, но я все еще получаю ту же ошибку
3. В чем
props.onSubmit
проблема? Тот, который передаетсяAddProduct
изconnect
HOC, тот, который передаетсяFormProduct
, или тот, который передаетсяform
элементу?4. @DrewReese HOC передается
addProduct
, а неonSubmit
, и HOC prop также вызывается правильно какprops.addProduct
, так что определенно не HOC из кода, который мы здесь показываем.5. @phry О, верно, слишком углубился при поиске использования «onSubmit».
Ответ №1:
Это не ошибка redux, поскольку onSubmit
это обычный react prop, который вы передаете вручную. Там может быть что-то не так, но из этих фрагментов не очевидно, что именно. Но ничего, связанного с сокращением.
Однако несколько слов о вашем использовании redux: если вы изучаете redux прямо сейчас, вы следуете устаревшему источнику. Redux значительно изменился за последние два года. Если вы будете следовать официальным рекомендациям, modern redux не будет содержать
- использование
connect
для компонентов функций (вместо этого используйтеuseDispatch
иuseSelector
) - типы строковых действий, написанных вручную
- написанные от руки действия или создатели действий
- использование switch …case или неизменяемой логики в редукторах
Пожалуйста, удалите любой учебник, который вы просматриваете, и вместо этого следуйте официальным руководствам redux. Вероятно, вы будете писать только 1/3 кода, который вы пишете прямо сейчас.
Комментарии:
1. Если вы имеете в виду redux-toolkit, то я согласен, это, безусловно, менее шаблонно. Я не согласен с рекомендацией отказаться от
connect
HOC, поскольку это позволяет вам писать независимые от redux / state-management презентационные компоненты пользовательского интерфейса.2. @DrewReese Я цитирую официальное руководство по стилю по этому поводу: redux.js.org/style-guide/style-guide / … Если вы хотите написать чисто презентационные компоненты, вы все равно можете сделать это с помощью хуков — разделив компоненты на «хуки» и «тупые» компоненты. Немного больше кода, но все же его намного легче освоить людям, привыкшим к современному React, чем работать с HOC. Большинство людей просто больше не делают этого различия, хотя в любом случае (большинство компонентов в конечном итоге получат useState amp; useEffect), поэтому применять его по умолчанию действительно не очень хорошая идея.