Почему URL не будет помещен в массив состояний? - PullRequest
0 голосов
/ 26 сентября 2019

Я пытаюсь поместить URL-адрес изображения, загруженный пользователем, в массив с последующим отображением этого изображения в представлении.С моим кодом все, что я получаю, это пустой [] в консоли.Почему никакие URL-адреса изображений не попадают в массив, а затем отображают это изображение в моем представлении?

Состояние и функция JS

this.state = {
            selectedFile: null,
            previewImgURL: '',
            pictures: []
        };
        this.imageUpload = this.imageUpload.bind(this);
}

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

        reader.onloadend = () => {
            this.setState({
                selectedFile: file,
                previewImgURL: reader.result,
                pictures: [...this.state.previewImgURL, this.state.previewImgURL]
            });
        };

        if (file) reader.readAsDataURL(file); // Allows user to preview image uploaded

        this.setState(() => ({file}));
        console.log(this.state.pictures); // in console, all I get's an empty []
    }

Код JSX:

    <div className="inputWrapper">
                    <input
                        id="new_post_image"
                        name="post_image"
                        className="button is-success is-outlined"
                        type="file"
                        style={{display: 'none'}}
                        onChange={this.imageUpload}
                        accept="image/*"
                    />
                    <label className="button is-success is-outlined" htmlFor="new_post_image">Upload</label>
                </div>

                {
                    this.state.pictures.map(key => (
                        <div className="uploaded-pics">
                            <Feed src={this.state.previewImgURL[key]} key={key} />
                        </div>
                    ))
                }
</div>

Вот Feed.js:

import React from 'react';
import './Feed.scss';

const feed = (props) => {
    return (
        <div className="row">
            <div className="col-md-6 col-sm-6">
                <img src={props.src}/>

            </div>
        </div>
    );
};

export default feed;

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Я думаю, что проблема заключается в том, что вы фактически добавляете изображения в состояние. this.setState({ selectedFile: file, previewImgURL: reader.result, ----> pictures: [...this.state.previewImgURL, this.state.previewImgURL] });

Когда вы используете оператор распространения, у вас фактически нет this.stateтак что this.state.previewImgURL еще не существует.

Я бы просто попытался:

this.setState({
  selectedFile: file,
  previewImgURL: reader.result,
  pictures: [reader.result]
});

Я также не уверен в использовании синтаксиса ... (распространение) в этом контексте.Если вы хотите просто обновить часть изображений состояния (если у вас уже есть состояние), вы можете использовать его как:

this.setState({
  ...this.state,
  pictures: [reader.result]
});

Еще одна вещь, на которую стоит обратить внимание, это то, что вы обновляете состояние в обратном вызове, чтобы ононе будет гарантировано заполнение при вызове вашего console.log(this.state.pictures)

Кроме того, вы находитесь в том же цикле, поэтому ваше состояние не было обновлено.

Для дополнительной отладки поместите какой-нибудь отладчик где-нибудь в Chrome DevTools и в консоль типа this.state.picture.Это отобразит часть изображения состояния и в отладчике вы также сможете перешагнуть через вашу программу.Зайдите сюда для получения дополнительной информации об отладке DevTools: https://developers.google.com/web/tools/chrome-devtools/javascript/

0 голосов
/ 26 сентября 2019

Быстро прочитайте Реагируйте на документацию setState .

Если вы console.log(this.state) сразу после setState, вы все еще находитесь в старом цикле, где состояния все еще остаютсястарое значение.

После изменения состояния срабатывает render, и если вы зарегистрируете там this.state, вы сможете увидеть обновленные состояния.

Другой способ немедленного доступаобновленное состояние - использование обратного вызова в качестве второго аргумента setState:

        reader.onloadend = () => {
            this.setState({
                selectedFile: file,
                previewImgURL: reader.result,
                pictures: [...this.state.previewImgURL, this.state.previewImgURL]
            }, () => {
                console.log(this.state.pictures) // this should show you the latest state
            });
        };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...