Свойства состояния не устанавливаются ["Это поле обязательно для заполнения."] - PullRequest
0 голосов
/ 09 марта 2019

У меня есть проект django / реагировать (s3 bucket для загрузки изображений), который добавляет рецепты в базу данных postgres.В моем компоненте RecipeFormContainer одно из моих свойств к рецептуре - это массив ингредиентов.Предполагается, что массив будет заполнен объектами, которые состоят из пар ключ-значение, единиц, количества и т. Д. Я написал метод addIngredients, но, похоже, он не добавляет объекты в мой массив ингредиентов.Я получаю ошибку "ингридиенты: [" Это поле обязательно для заполнения. "]" При попытке отправить мой рецепт и сделать сообщение.Пожалуйста, просветите меня тем, чего мне не хватает.Код выглядит следующим образом:

import React, {Component} from 'react';
import {Form} from 'react-bootstrap'
import Button from 'react-bootstrap/Button';


class RecipeFormContainer extends Component {
    constructor(props) {
        super(props);

        this.state = {
            title: '',
            creator: '',
            mealTime: "",
            prepTime: "",
            cookTime: "",
            image_preview: "",
            servings: "",
            directions: '',
            ingredients: [{
                units: '',
                amounts: '',
                multiples: '',
                quantity: '',
                name: ''
            }],
            image: "",

        };

        this.handleImage = this.handleImage.bind(this);
        this.handleIngredientInput = this.handleIngredientInput.bind(this);
        this.handleAddIngredients = this.handleAddIngredients.bind(this);
    }

    handleAddIngredients =(e) => {
        e.preventDefault();

// the ingredients properties are not being added to the ingredients array property on state *************************

        let ingredient = {units: '',
                amounts: '',
                multiples: '',
                quantity: '',
                name: ''};

        //save the current state of ingredients array in variable ingredient
        let {ingredients} = this.state.ingredients;
        // add the ingredient object into the ingredients array ( which is a property of state)
        ingredients.push(ingredient);

        // set the new array of ingredients as the state of the property ingredients
        this.setState( {ingredients: ingredients});
    };



    handleInput = (e) => {
        e.preventDefault();
        this.setState({[e.target.name]: e.target.value});

    };


    handleIngredientInput = (e) => {
        e.preventDefault();
        this.setState({[e.target.name]: e.target.value})
    };

    handleImage(event) {
        event.preventDefault();
        // this makes it show up in preview

        let file = event.target.files[0];
        let fileReader = new FileReader();
        fileReader.onloadend = () => this.setState({image_preview:fileReader.result});
        fileReader.readAsDataURL(file);
        this.setState({image:file});
    }



    submitRecipe = (event) => {
        event.preventDefault();
        let recipe = {...this.state};
        console.log('recipe one', this.state);

        let formData = new FormData();

        formData.append("image", this.state.image);
        formData.append('title', this.state.title);
        formData.append("ingredients", this.state.ingredients);
        formData.append("mealTime", this.state.mealTime);
        formData.append("prepTime", this.state.prepTime);
        formData.append("cookTime", this.state.cookTime);
        formData.append("image_Preview", this.state.image_preview);
        formData.append("servings", this.state.servings);
        formData.append("directions", this.state.directions);
        formData.append("creator", this.state.creator);
        // formData.append("units", this.state.ingredients.units);
        // formData.append("amount", this.state.ingredients.amount);
        // formData.append("multiples", this.state.ingredients.multiples);
        // formData.append("quantity", this.state.ingredients.quantity);
        // formData.append("name", this.state.ingredients.name);

        // add line for each property of state


        const conf = {
            method: "POST",
            body: formData,

        };

        fetch('/api/recipe/', conf).then((response) => {

            return response.json();

        }).then((json) => {
            this.props.addRecipe(json);

        });


    };


    render() {


        return (


            <Form onSubmit={this.submitRecipe} encType="multipart/form-data"  >

                <Form.Group onSubmit={event => {event.preventDefault(); }}  >
                    <img src={this.state.image_preview}/>
                    <input className="input" type="file"  onChange={this.handleImage} name="image" />
                </Form.Group>

                <Form.Group controlId="exampleForm.ControlInput1">
                    <Form.Label>Recipe Name</Form.Label>
                    <Form.Control type="text" placeholder="Enter Recipe Name Here"
                                  name="title"
                                  value={this.state.title}
                                  onChange={this.handleInput}/>


                    <Form.Label>Recipe Creator</Form.Label>
                    <Form.Control type="text" placeholder="Enter Your Name Here"
                                  value={this.state.creator}
                                  name="creator"
                                  onChange={this.handleInput}/>

                </Form.Group>

                <Form.Group controlId="exampleForm.ControlSelect1" id="foodType">
                    <Form.Label>Example select</Form.Label>
                    <Form.Control as="select">
                        <option>Breakfast</option>
                        <option>Lunch</option>
                        <option>Dinner</option>
                        <option>Dessert</option>
                        <option>Vegetarian</option>
                    </Form.Control>
                </Form.Group>


                <Form.Control type="text" placeholder="Prep Time" className="midButt"
                              value={this.state.prepTime}
                              name="prepTime"
                              onChange={this.handleInput}/>
                <Form.Control type="text" placeholder="Cook Time" className="midButt"
                              value={this.state.cookTime}
                              name="cookTime"
                              onChange={this.handleInput}/>


                <Form.Group controlId="exampleForm.ControlSelect1" id="foodTemp">
                    <Form.Control as="select">
                        <option>Fahrenheit</option>
                        <option>Celsius</option>
                    </Form.Control>
                </Form.Group>


                <Form.Group>
                    This Recipe Will Make: <Form.Control type="number" placeholder="servings" id="servings" value={this.state.ingredients.servings} onChange={this.handleInput} name="servings" />

                    <Form.Control type="text" placeholder="cookies, loaves, etc." id="loaf" value={this.state.ingredients.multiples} onChange={this.handleIngredientInput} name="multiples"/>

                </Form.Group>

                {this.state.ingredients.map((ingredient, index) => {
                    return (
                        <div key={index}>
                            <Form.Control type="number" placeholder="#" id="numberAmount" value={this.state.ingredients.quantity} onChange={this.handleIngredientInput} name="amount"/>
                            <Form.Control type="text" placeholder="units" id="units" value={this.state.ingredients.units} onChange={this.handleIngredientInput} name="units"/>
                            <Form.Control type="text" placeholder="Ingredient Name" id="name" value={this.state.ingredients.name} onChange={this.handleIngredientInput} name="name"/>
                        </div>
                    );
                })};

                <Button variant="light" onClick = {this.handleAddIngredients}> + </Button>
                {/*/!*will update state with event handler this.state.ingredients, append object to array *!/*/}


                <Form.Group controlId="exampleForm.ControlTextarea1">
                    <Form.Label>Directions</Form.Label>
                    <Form.Control as="textarea" rows="3"
                        value={this.state.directions}
                              name="directions"
                              onChange={this.handleInput}/>
                </Form.Group>


                <Button type="submit" variant="secondary">Save This Recipe !</Button>

            </Form>
        )
    };
}


export default RecipeFormContainer;
   

1 Ответ

0 голосов
/ 09 марта 2019

Взглянув на ваш код, ваш handleAddIngredients не прав. Вы допустили две ошибки:

Не сбор данных с входов

Вы не собираете данные из штата, чтобы поместить их в ingredient. Ваш код создает пустое значение ingredient для размещения в массиве.

Попытка скопировать массив ingredients неверным способом.

Ваш код "извлекает" ingredients из this.state.ingredients, но это невозможно. Ваш ingredients принадлежит вашему state, а не state.ingredients.

Вместо того, чтобы делать

let { ingredients } = this.state.ingredients

Вы могли бы сделать

let { ingredients } = this.state

Или даже

let ingredients = [ ...this.state.ingredients ]

Заключение

После всех исправлений ваш код должен выглядеть следующим образом:

handleAddIngredients = (e) => {
     e.preventDefault();

    //Extracting the values from the state
    let { units, amounts, multiples, quantity, name } = this.state

    // Inserting the values into the new ingredient
    let ingredient = { units, amounts, multiples, quantity, name }

    // Creating the copy
    let ingredients = [ ... this.state.ingredients ]

    // add the ingredient object into the ingredients array ( which is a property of state)
    ingredients.push(ingredient);

    // set the new array of ingredients in the state
    this.setState({ingredients});
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...