Nicolas Albarracin
Nicolas Albarracin

Reputation: 217

Uploading images to state in react

I'm working on uploading images on my react app, the idea is to save the images in my object, send it to my back end and upload them to clodinary but right now i cant seem to put the files in my object array:

Component:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types';
import Dropzone from 'react-dropzone';
import {
    Grid,
    Row,
    Col,
    FormControl,
    FormGroup,
    Button,
    ButtonToolbar,
    Label
} from 'react-bootstrap';

import {Dwelling} from '../../../model';
import {requestSaveDwelling} from '../../../actions';

class New3 extends Component {
    static propTypes = {
        requestSaveDwelling: PropTypes.func.isRequired,
        history: PropTypes.shape({
            push: PropTypes.func.isRequired
        }).isRequired,
        dwelling: PropTypes.shape({})
    };

    static defaultProps = {
        dwelling: new Dwelling()
    };

    constructor(props) {
        super(props);
        this.state = {dwelling: new Dwelling()};
        if (this.props.dwelling) {
            this.state = this.props;
        }
    }

    handleChange({target: {id, value}}) {
        this.setState(
            state => ({
                dwelling: (Object.assign(state.dwelling, {[id]: value}))
            })
        );
    }

    handleDrop(file) {
        this.setState(
            state => ({
                dwelling: (Object.assign(state.dwelling.images, file))
            })
        );
    }


    handleSubmit() {
        const {dwelling} = this.state;
        this.props.requestSaveDwelling(dwelling);
        this.props.history.push('/dwellings/latest');
    }

    render() {
        const {dwelling} = this.state;
        console.log(dwelling);
        return (
            <Grid className="animated fadeIn">
                <Row>
                    <Col sm={12}>
                        <h2>Carga de Imágenes</h2>

                        <Dropzone
                            onDrop={this.handleDrop}
                            multiple
                            accept="image/*"
                        >
                            <p>Arrastre Imagenes aquí, o haga click para seleccionar imagenes.</p>
                        </Dropzone>
                        {this.state.dwelling.images.length > 0 ?
                            <div>
                                <h2>Uploading {this.state.dwelling.images.length} files...</h2>
                                <div>{this.state.dwelling.images.map(file => <img src={file.preview}/>)}</div>
                            </div> : null}
                    </Col>
                </Row>
                <Row>
                    <Col sm={12}>
                        <FormGroup controlId="occupationStatus">
                            <Label>Estado Ocupacional</Label>
                            <FormControl
                                componentClass="select"
                                value={dwelling.occupationStatus}
                                placeholder="Seleccione"
                                onChange={e => this.handleChange(e)}
                            >
                                <option disabled label="Seleccione"/>
                                <option value="Disponible" label="Disponible"/>
                                <option value="Alquilada" label="Alquilada"/>
                                <option value="Vendida" label="Vendida"/>
                                <option value="Reservada" label="Reservada"/>
                                <option value="Suspendida" label="Suspendida"/>
                            </FormControl>
                        </FormGroup>
                    </Col>
                </Row>
                <Row>
                    <Col sm={12}>
                        <h2>Descripción General</h2>
                        <FormGroup controlId="generalDescription">
                            <FormControl
                                componentClass="textarea"
                                value={dwelling.generalDescription}
                                onChange={e => this.handleChange(e)}
                                placeholder="Escriba una Descripcion general"
                            />
                        </FormGroup>
                    </Col>
                </Row>
                <Row>
                    <Col sm={12}>
                        <h2>Descripción Privada</h2>
                        <FormGroup controlId="privateDescription">
                            <FormControl
                                componentClass="textarea"
                                value={dwelling.privateDescription}
                                onChange={e => this.handleChange(e)}
                                placeholder="Escriba una Descripcion privada"
                            />
                        </FormGroup>
                    </Col>
                </Row>
                <Row>
                    <Col sm={6}>
                        <ButtonToolbar className="pull-left">
                            <Button href="#/dwellings/new2">Atrás</Button>
                        </ButtonToolbar>
                    </Col>
                    <Col sm={6}>
                        <ButtonToolbar className="pull-right">
                            <Button onClick={() => this.handleSubmit()}>Guardar</Button>
                        </ButtonToolbar>
                    </Col>
                </Row>
            </Grid>
        );
    }
}

export default connect(
    state => ({
        dwelling: state.dwelling.dwelling
    }),
    dispatch => ({
        requestSaveDwelling: dwelling => dispatch(requestSaveDwelling(dwelling))
    })
)(New3);

object model:

export default class Dwelling {
    _id = undefined;
    publicationType = '';
    address = {
        address: '',
        latitude: null,
        longitude: null
}
    images = [];
constructor(obj) {
        Object.assign(this, obj);
    }
}

when i try to upload an image i get this error: New3.js:51 Uncaught TypeError: Cannot read property 'images' of undefined at Dropzone. (New3.js:51)

Upvotes: 0

Views: 4674

Answers (1)

ionizer
ionizer

Reputation: 1721

This is my example of my previewer with FileReader. However, this is only one file so you might want to adjust it for your app.

class Preview extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      previewSrc: ''
    }
  }

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

    let file = e.target.files[0];
    let reader = new FileReader();

    if (e.target.files.length === 0) {
      return;
    }

    reader.onloadend = (e) => {
      this.setState({
        previewSrc: [reader.result]
      });
    }

    reader.readAsDataURL(file);
  }
  
  render() {
    return (
      <div id="previewer">
        <input type="file" onChange={this.handlePreview} />
        <h1>Preview</h1>
        <img src={this.state.previewSrc} alt="" />
      </div>
    );
  }
}

ReactDOM.render(<Preview/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>

<div id="root"></div>

References:

Upvotes: 2

Related Questions