Невозможно выполнить итерацию по массиву, переданному в качестве реквизита для дочернего компонента React js - PullRequest
0 голосов
/ 22 января 2020

У меня есть компонент реагирования, где я получаю контактную информацию людей из Google People API после получения их разрешения. Я собираю имена контактов, электронную почту, номера телефонов и адреса в массиве. Затем я передаю массив в качестве опоры дочернему компоненту. Но хотя дочерний компонент, очевидно, получает опору, консоль говорит, что его длина равна нулю.

Вывод на консоль выглядит следующим образом: Preview of react component

Код, в котором я строю массив объектов, выглядит следующим образом (ранее я построил весь объект, теперь Я просто добавляю строки, чтобы проверить, работает ли он, но мне нужно передать массив объектов в подпорки компонента):

    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>
)
* 1013 И, наконец, в дочернем компоненте я делаю это (после установки состояния в конструкторе):
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) -. Я также проверил функцию карты, и она работает правильно, когда я использую постоянное значение 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 ]

1 голос
/ 22 января 2020

В дочернем компоненте вы пытаетесь получить доступ к this.state.Contactos, но передаете список контактов как свойство initialize. Он должен быть доступен внутри дочернего компонента как this.props.initialize.

0 голосов
/ 22 января 2020

Этот ответ основан на моем предположении, так как я не могу проверить весь исходный код. Я предполагаю, что компонент 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
});

Кроме того, из официального документа ,

состояние является ссылкой на состояние компонента во время применения изменения. Он не должен быть напрямую мутирован.

Поэтому вместо того, чтобы делать

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 будет поверхностно объединять новое состояние с предыдущим для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...