无法迭代作为道具传递给React js子组件的数组

时间:2020-01-22 00:59:53

标签: reactjs properties state

我有一个react组件,可以在获得人们许可后从Google People API收集人们的联系信息。我收集数组中的联系人姓名,电子邮件,电话号码和地址。然后,将数组作为道具传递给子组件。但是,尽管子组件显然收到了道具,但控制台表示其长度为零。

控制台输出如下: Preview of react component

构建对象数组的代码是这样的(我之前已经构建了整个对象,现在我只是追加字符串以测试其是否正常工作,但是我需要将对象数组传递给组件props):

    var Elementos = [];
    (I call the google api here).then(function (resp) {

            var Fila = 0;
            resp.result.connections.forEach(list => {
                var Contacto = {}
                if (list.names != undefined && list.names.length > 0) {
                    Contacto.Nombre = list.names[0].displayName;
                }
                if (list.emailAddresses != undefined && list.emailAddresses.length > 0) {
                    Contacto.Email = list.emailAddresses[0].value;
                }
                if (list.addresses != undefined && list.addresses.length > 0) {
                    Contacto.Direccion = list.addresses[0].value;
                }
                if(list.phoneNumbers != undefined && list.phoneNumbers.length > 0){
                    var telefonos = "";
                    list.phoneNumbers.forEach(item=>{
                        telefonos+=item.value+",";
                    })
                    telefonos = telefonos.substring(0, telefonos.length-1);
                    Contacto.Telefono = telefonos;
                }
                if (list.names != undefined && list.names.length > 0 && list.emailAddresses != undefined && list.emailAddresses.length > 0 && list.phoneNumbers != undefined && list.phoneNumbers.length > 0) {
                    Fila++;
                    Contacto.Numero = Fila;
                    Elementos.push(Contacto.Nombre +" "+Contacto.Telefono);
                }
            });
            return resp;
        })
        return datos;
    }).then((respuesta) => {
        this.setState(prevEstado => {
            prevEstado.Contactos = Elementos, prevEstado.DirectorioCargado = true;
            return prevEstado});});

然后我传递如下属性:

return (
    <div>
        <DirectorioContactos titulo="Directorio de contactos" initialize={this.state.Contactos} />
    </div>
)

最后在子组件中,我要这样做(在构造函数中设置状态之后):

render() {
        console.log('en propiedades');
        console.log(this.state.Contactos);
        console.log(this.state.Contactos.length);

        const algo = ["Entonces","Tu","Valiste","Tres kilos"];
        return (
            <div>
            <Jumbotron>
                <h2>{this.props.titulo}</h2>
                <p>Invita a los contactos que desees. Les enviaremos un correo informando tu decisión de agregarlos a nuestro directorio.</p>
            </Jumbotron>
            <Table striped bordered condensed hover>
                <thead>
                    <tr>
                        <th>#</th>
                        <th>Nombre y Apellidos</th>
                        <th>Teléfono</th>
                        <th>Correo electrónico</th>
                        <th>Dirección</th>
                    </tr>
                </thead>
                <tbody>{this.state.Contactos.map((item, i) => {
            return(<tr key={i}>
                <td>{i}</td>
                <td>{item}</td>
                <td></td>
                <td></td>
                <td></td>
                </tr>);})
                }</tbody>
            </Table>
            </div>
        );
    }

但是,正如您在图像中看到的那样,什么都没有呈现-控制台中读取图像中0的行(如果您仔细看的话)是对console.log(the property.length)的调用的输出。我还测试了map函数,当我使用像algo这样的常数值algo.map((item, i)时,它可以正常工作。

所以我的问题是'我做错了什么?请考虑一下,我是React的新手,从我的阅读中我了解到可以传递这样的属性,甚至说我理解这是React js的目的。

更新:从我读过的评论(以及我读到的有关React js的内容)中,我真的认为我缺少了一些我无法在此处表达的内容:我认为这是我对状态的理解道具是,因为我发现问题是在设置Contactos状态时开始的。我是这样做的:

.then((respuesta) => {
                this.setState({Contactos:Elementos, DirectorioCargado :true
                },()=>{
                    console.log('Después de cargar estado');
                    console.log(this.state.Contactos);
                    console.log(this.state.Contactos.length);
                });

从右边开始,它显示数组中的长度为零,尽管日志中显示了元素。作为参考,我在父组件的构造函数中执行此操作:

super();
        this.state = {
            Persona: {
                Nombres: '',
                ApellidoPaterno: '',
                ApellidoMaterno: '',
                Telefono: '',
                Calle: '',
                NumeroExterior: '',
                NumeroInterior: '',
                Colonia: '',
                Localidad: '',
                EntidadFederativa: '',
                CodigoPostal: '',
                Email: '',
                Mensaje: '',
                RecibeOfertas: false,
                InvitaContactos: false,
            },
            Contactos: [],
            DirectorioCargado: false

我再次询问,有没有一种方法可以正确设置数组属性Contactos。如我所说,我只是从React开始。

2 个答案:

答案 0 :(得分:1)

在子组件中,您尝试访问this.state.Contactos,但是将联系人列表作为initialize属性传递。它应该在子组件内部以this.props.initialize的形式提供。

答案 1 :(得分:0)

此答案基于我的假设,因为我无法检查整个源代码。我猜想DirectorioContactos组件是PureComponent。

假设您有一个带有状态的React组件,并像这样初始化了它

var Elementos = [];
this.state = {
  Contactos: Elementos
}

// in render
<PureChildComponent initialize={this.state.Contactos} />

然后您像这样更新它

Elementos.push("foo");
this.setState({
  Contactos: Elementos
});

如果PureChildComponent是PureComponent,则即使您更新Elementos也不会重新渲染它。这是因为您通过直接对其进行突变来更新Contactos,这意味着Contactos的引用未更改。除非引用被更新,否则React不会重新渲染PureComponent。 因此,正确的方法不是Elementos.push("foo");,而是

this.setState({
  Contactos: [...Elementos, "foo"] // always create a new array
});


此外,从official document

state是在应用更改时对组件状态的引用。它不应该直接变异。

所以不要这样做

this.setState(prevEstado => {
  prevEstado.Contactos = Elementos, prevEstado.DirectorioCargado = true;
  return prevEstado;
});

正确的方法是

this.setState(prevEstado => ({
  ...prevEstado,
  Contactos: Elementos,
  DirectorioCargado: true,
}));

或者只是

this.setState({
  Contactos: Elementos,
  DirectorioCargado: true,
});

因为React会为您将新状态与上一个状态浅层合并。