如何在React JS中的MultiSelect Component的props处分配数组

时间:2019-05-14 19:17:14

标签: reactjs multi-select

我试图在React JS的MultiSelect组件的props“ options”上分配一个数组,我需要数组中的特定格式,但是屏幕为空白并且我得到options.map不是一个函数错误,数组返回成功(可以),我不明白为什么会发生该错误。

我的代码是:

//I get data array

axios({
    method: 'get',
    url: `${URL}/suscripcion`,
    headers: {
        "Authorization": "bearer " + TOKEN
    }
}).then(respuesta => {
    let datos = respuesta.data;

    if (datos.success) {
        this.setState({
            Suscritos: datos.data
        });
        sus = this.state.Suscritos;
    } else {
        console.log("no")
    }
});


//Return array with format

Listarprueba() {
        if (this.state.Suscritos.length > 0) {
            return this.state.Suscritos.map((e, i) =>
            [
                {label: `${e.Email}`, value: `${e.Email}`}
            ]
            );
        }
    }

//Asign array at options

    options = this.Listarprueba();

//This is the MultiSelect Component

<div>
    <h1>Multiselect dropdown</h1>
    <Multiselect
        options={this.options}
        onSelectedChanged={this.handleSelectedChanged}
        selected={selected}
        isLoading={isLoading}
        disabled={isLoading}
        disableSearch={false}
        overrideStrings={{
            selectSomeItems: "do me a favor by selecting something",
            allItemsAreSelected: "You have gone nuts... all selected",
            selectAll: "do u wanna select all of them?",
            search: "Fantasy search"
        }}
    />
</div>

我得到了数组enter image description here的数据

这是错误enter image description here

我在这里找到了示例https://codesandbox.io/s/3k3vjplo5

我认为错误在于选项道具。

options={this.options}

我想知道如何在react js中成功实现MultiSelect。

好的,这是我所有的组件代码:

        import React, { Component, Fragment } from 'react';
        import { injectIntl } from 'react-intl';
        import { Colxx, Separator } from "Components/CustomBootstrap";
        import BreadcrumbContainer from "Components/BreadcrumbContainer";
        import IntlMessages from "Util/IntlMessages";
        import { Row, Card, CardBody, CardTitle, Input, Label, Button, } from "reactstrap";
        import ReactQuill from "react-quill";
        import "react-quill/dist/quill.snow.css";
        import 'react-quill/dist/quill.bubble.css';
        import { Formik, Field, Form } from 'formik';
        import * as Yup from 'yup';
        import axios from 'axios';
        import { URL, TOKEN } from 'Util/Config/Config';
        import SweetAlert from 'sweetalert-react';
        import Multiselect from "@khanacademy/react-multi-select";

        class CrearNotificacion extends Component {

            constructor(props) {
                super(props);
                this.state = {
                    textQuillBubble: "",
                    Suscritos: [],
                    sweetshow: false,
                    sweetTitle: '',
                    sweetText: '',
                    sweetType: '',
                    selected: [],
                    isLoading: true
                };
                this.handleChangeQuillBubble = this.handleChangeQuillBubble.bind(this);
            }

            Notificaciones = {
                Asunto: '',
                Suscripcion: '',
                Notificacion: '',
            }

    handleChangeQuillBubble(textQuillBubble) {
            this.setState({ textQuillBubble });
        }

        componentDidMount() {
            axios({
                method: 'get',
                url: `${URL}/suscripcion`,
                headers: {
                    "Authorization": "bearer " + TOKEN
                }
            }).then(respuesta => {
                let datos = respuesta.data;

                if (datos.success) {
                    this.setState({
                        Suscritos: datos.data
                    });
                    sus = this.state.Suscritos;
                } else {
                    console.log("no")
                }
            });
            setTimeout(() => {
                this.setState({
                    isLoading: false
                });
            }, 5000);
        }

    handleSelectedChanged = selected => {
            this.setState({ selected });
        };

        Guardar(value) {
            axios({
                method: 'post',
                url: `${URL}/notificacion`,
                headers: {
                    "Authorization": "bearer " + TOKEN,
                },
                data: {
                    Asunto: value.Asunto,
                    Suscripcion: value.Email,
                    Notificacion: this.state.textQuillBubble,
                }
            }).then((respuesta) => {
                let datos = respuesta.data;
                if (datos.success) {
                    this.setState({
                        sweetshow: true,
                        sweetText: datos.mensaje,
                        sweetTitle: "Mensaje",
                        sweetType: "success"
                    });
                } else {
                    this.setState({
                        sweetshow: true,
                        sweetText: datos.error,
                        sweetTitle: "Mensaje",
                        sweetType: "error"
                    });
                }
            });
        }

        Cancelar() {
            this.props.history.goBack();
        }

        Listarprueba() {
            if (this.state.Suscritos.length > 0) {
                return this.state.Suscritos.map((e, i) => (
                    { label: `${e.Email}`, value: `${e.Email}` }
                ));
            }
        }

        options = this.Listarprueba();

     render() {
            const { selected, isLoading } = this.state;
            return (
                <Fragment>
                    <Row>
                        <Colxx xxs="12">
                            <h1>{<IntlMessages id="menu.NewNoti" />}</h1>
                            <Separator className="mb-5" />
                        </Colxx>
                    </Row>
                    <Row className="mb-4">
                        <Colxx xxs="12">
                            <Card>
                                <CardBody>
                                    <Formik
                                        initialValues={this.Notificaciones}
                                        validationSchema={NotificacionSchema}
                                        onSubmit={value => {
                                            this.Guardar(value);
                                        }}
                                    >
                                        {({ errors, touched, values }) => (
                                            <div>
                                                <Form className="av-tooltip tooltip-label-bottom">
                                                    <Label className="form-group has-float-label">
                                                        <Field type="text" maxLength="45" name="Asunto" className="form-control" />
                                                        {errors.Asunto && touched.Asunto ? (
                                                            <div className="invalid-feedback d-block">{errors.Asunto}</div>
                                                        ) : null}
                                                        <IntlMessages id="forms.asunto" />
                                                    </Label>

<Label className="form-group has-float-label">
                                                    {/* <Field type="hidden" name="Mensaje"/> */}
                                                    <ReactQuill
                                                        theme="bubble"
                                                        value={this.state.textQuillBubble}
                                                        onChange={this.handleChangeQuillBubble}
                                                    />
                                                    {/* {errors.Mensaje && touched.Mensaje ? (
                                                        <div className="text-danger">{errors.Mensaje}</div>
                                                    ) : null} */}
                                                    <IntlMessages id="forms.Notificacion" />
                                                </Label>
                                                <div>
                                                    <h1>Multiselect dropdown</h1>
                                                    {console.log(this.state.Suscritos)}
                                                    <Multiselect
                                                        options={this.options}
                                                        onSelectedChanged={this.handleSelectedChanged}
                                                        selected={selected}
                                                        isLoading={isLoading}
                                                        disabled={isLoading}
                                                        disableSearch={false}
                                                        overrideStrings={{
                                                            selectSomeItems: "do me a favor by selecting something",
                                                            allItemsAreSelected: "You have gone nuts... all selected",
                                                            selectAll: "do u wanna select all of them?",
                                                            search: "Fantasy search"
                                                        }}
                                                    />
                                                    {/* {selected.join(", ")} */}
                                                </div>
                                                <br />
                                                <Button color="primary col-6" type="submit">
                                                    <IntlMessages id="forms.submit" />
                                                </Button>
                                                <Button color="secondary col-6" onClick={() => this.Cancelar()}>
                                                    <IntlMessages id="forms.Cancelar" />
                                                </Button>
                                            </Form>
                                        </div>
                                    )}
                                </Formik>
                                <SweetAlert
                                    show={this.state.sweetshow}
                                    title={this.state.sweetTitle}
                                    text={this.state.sweetText}
                                    type={this.state.sweetType}
                                    onConfirm={() => {
                                        this.setState({ sweetshow: false })
                                        this.props.history.push('app/Contacto/Notificaciones/Notificacion')
                                    }}
                                />
                            </CardBody>
                        </Card>
                    </Colxx>
                </Row>
            </Fragment>
        );
    }
}
export default injectIntl(CrearNotificacion);

2 个答案:

答案 0 :(得分:0)

更新此代码以返回对象数组,而不是数组数组,像这样:

Listarprueba = () => {
  if (this.state.Suscritos.length > 0) {
    return this.state.Suscritos.map((e, i) => (
      {label: `${e.Email}`, value: `${e.Email}`}
    ));
  }
}

这将返回[{label:'emailstring', value:'emailstring'}, {},{}...];,您的原始文件将返回[ [{label:'emailstring', value:'emailstring'}],[{}], [{}], ...]

答案 1 :(得分:0)

由于rest调用,您正在做异步操作,因此它试图在包含数据之前进行渲染。在渲染可能没有数据的东西之前进行检查,例如

options={this.options ? this.options : []}

if (this.state && this.state.Suscritos && this.state.Suscritos.length > 0) {
...
}