我有一个react组件,可以在获得人们许可后从Google People API收集人们的联系信息。我收集数组中的联系人姓名,电子邮件,电话号码和地址。然后,将数组作为道具传递给子组件。但是,尽管子组件显然收到了道具,但控制台表示其长度为零。
构建对象数组的代码是这样的(我之前已经构建了整个对象,现在我只是追加字符串以测试其是否正常工作,但是我需要将对象数组传递给组件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开始。
答案 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
});
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会为您将新状态与上一个状态浅层合并。