Dropdown do primereact

16 respostas
react
guilhermebhte

Estou precisando preencher o componente Dropdown do primereact, de informações que vem do banco de dados, mas está ficando em branco.

Nesta parte do código ele vai no backend, mas mesmo assim não está preenchendo as informações no componente.

let a = [
          ApiGrupoService.todos().then(
            res => {
              return res;
          })
        ]

Código completo

import React, { Component } from 'react';

import ApiUsuarioService from '../../service/ApiServiceUsuario';
import ApiGrupoService from '../../service/ApiServiceGrupo';

import {InputText} from 'primereact/inputtext';
import {Button} from 'primereact/button';
import {Growl} from 'primereact/growl';
import {Calendar} from 'primereact/calendar';
import {Dropdown} from 'primereact/dropdown';

class UsuarioForm extends Component {

  constructor(props) {
    super(props);
    this.usuario = {
        id: null,
        grupo: null,
        nome: null,
        sobrenome: null,
        dataAniversario: null
    }
    this.salvarUsuario = this.salvarUsuario.bind(this);
  }

  salvarUsuario = (e) => {
    e.preventDefault();
    let usuario = {id: this.state.id, 
      grupo: this.state.grupo,
      nome: this.state.nome,
      sobrenome: this.state.sobrenome,
      dataAniversario: this.state.dataAniversario};
      ApiUsuarioService.salvar(usuario).then(res => {
        this.growl.show({severity: res.data.tipoMensagem.tipo, 
            summary: res.data.tipoMensagem.sumario, 
            detail: res.data.tipoMensagem.mensagem});
      }, (err) => {
          this.growl.show({severity: err.response.data.tipoMensagem.tipo, 
              summary: err.response.data.tipoMensagem.sumario, 
              detail: err.response.data.tipoMensagem.mensagem});
      });
  }

  render() {

    let a = [
      ApiGrupoService.todos().then(
        res => {
          return res;
      })
    ]
    
    return (
      <div>
            <Growl ref={el => (this.growl = el)} />
            <h1>Grupo *</h1>
            <Dropdown value={this.usuario.grupo} options={a}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>
            <h1>Nome *</h1>
            <InputText value={this.usuario.nome} 
                onChange={(e) => this.setState({nome: e.target.value})} /><br/>
            <h1>Sobrenome *</h1>
            <InputText value={this.usuario.sobrenome} 
                onChange={(e) => this.setState({sobrenome: e.target.value})} /><br/>
            <h1>Aniversário *</h1>
            <Calendar value={this.usuario.dataAniversario} dateFormat="dd/mm/yy"
                onChange={(e) => this.setState({dataAniversario: e.value})} /><br/>
            <Button onClick={this.salvarUsuario} label="Salvar" />
        </div>
    );
  }
}

export default UsuarioForm;

Erro no console do navegador:

index.js:1375 Warning: Each child in a list should have a unique "key" prop.

Check the render method of `Dropdown`. See https://fb.me/react-warning-keys for more information.
    in DropdownItem (created by Dropdown)
    in Dropdown (at usuario-form.js:64)
    in div (at usuario-form.js:61)
    in UsuarioForm (created by Context.Consumer)
    in Route (at src/index.js:17)
    in Switch (at src/index.js:14)
    in Router (created by BrowserRouter)
    in BrowserRouter (at src/index.js:13)

16 Respostas

Mike

As atualizações não estão ocorrendo pq o seu objeto não esta setado no state.
Quando o state muda, o render é executado novamente atualizando os valores.

Coloca o seu usuario dentro do state

guilhermebhte

Não entendi …

Mike
ApiGrupoService.todos().then(
    res => {
      return res;
  })

Executa essa chamada no componentDidMount e seta no state o response
Ex:

componentDidMount() {
  this.setState({
    grupos: [ApiGrupoService.todos().then(
      res => {
        return res;
      }
    )
  })
}

No Dropdown você passa os grupos

<Dropdown value={this.usuario.grupo} options={this.state.grupos}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>

Os componentes do seu render só vão ter o valor atualizado caso o state ou props mude.

guilhermebhte

Fiz assim e não está chamando mais o backend.

import React, { Component } from 'react';

import ApiUsuarioService from '../../service/ApiServiceUsuario';
import ApiGrupoService from '../../service/ApiServiceGrupo';

import {InputText} from 'primereact/inputtext';
import {Button} from 'primereact/button';
import {Growl} from 'primereact/growl';
import {Calendar} from 'primereact/calendar';
import {Dropdown} from 'primereact/dropdown';

class UsuarioForm extends Component {

  constructor(props) {
    super(props);
    this.usuario = {
        id: null,
        grupo: null,
        nome: null,
        sobrenome: null,
        dataAniversario: null
    }
    this.salvarUsuario = this.salvarUsuario.bind(this);
  }

  salvarUsuario = (e) => {
    e.preventDefault();
    let usuario = {id: this.state.id, 
      grupo: this.state.grupo,
      nome: this.state.nome,
      sobrenome: this.state.sobrenome,
      dataAniversario: this.state.dataAniversario};
      ApiUsuarioService.salvar(usuario).then(res => {
        this.growl.show({severity: res.data.tipoMensagem.tipo, 
            summary: res.data.tipoMensagem.sumario, 
            detail: res.data.tipoMensagem.mensagem});
      }, (err) => {
          this.growl.show({severity: err.response.data.tipoMensagem.tipo, 
              summary: err.response.data.tipoMensagem.sumario, 
              detail: err.response.data.tipoMensagem.mensagem});
      });
  }


  componentDidMount() {
    this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => this.setState({usuarios: res.data.lista})
      )]
    })
  }
  
  render() {
    
    return (
      <div>
            <Growl ref={el => (this.growl = el)} />
            <h1>Grupo *</h1>
            <Dropdown value={this.usuario.grupo} options={this.state.grupos}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>
            <h1>Nome *</h1>
            <InputText value={this.usuario.nome} 
                onChange={(e) => this.setState({nome: e.target.value})} /><br/>
            <h1>Sobrenome *</h1>
            <InputText value={this.usuario.sobrenome} 
                onChange={(e) => this.setState({sobrenome: e.target.value})} /><br/>
            <h1>Aniversário *</h1>
            <Calendar value={this.usuario.dataAniversario} dateFormat="dd/mm/yy"
                onChange={(e) => this.setState({dataAniversario: e.value})} /><br/>
            <Button onClick={this.salvarUsuario} label="Salvar" />
        </div>
    );
  }
}

export default UsuarioForm;

e assim:

import React, { Component } from 'react';

import ApiUsuarioService from '../../service/ApiServiceUsuario';
import ApiGrupoService from '../../service/ApiServiceGrupo';

import {InputText} from 'primereact/inputtext';
import {Button} from 'primereact/button';
import {Growl} from 'primereact/growl';
import {Calendar} from 'primereact/calendar';
import {Dropdown} from 'primereact/dropdown';

class UsuarioForm extends Component {

  constructor(props) {
    super(props);
    this.usuario = {
        id: null,
        grupo: null,
        nome: null,
        sobrenome: null,
        dataAniversario: null
    }
    this.salvarUsuario = this.salvarUsuario.bind(this);
  }

  salvarUsuario = (e) => {
    e.preventDefault();
    let usuario = {id: this.state.id, 
      grupo: this.state.grupo,
      nome: this.state.nome,
      sobrenome: this.state.sobrenome,
      dataAniversario: this.state.dataAniversario};
      ApiUsuarioService.salvar(usuario).then(res => {
        this.growl.show({severity: res.data.tipoMensagem.tipo, 
            summary: res.data.tipoMensagem.sumario, 
            detail: res.data.tipoMensagem.mensagem});
      }, (err) => {
          this.growl.show({severity: err.response.data.tipoMensagem.tipo, 
              summary: err.response.data.tipoMensagem.sumario, 
              detail: err.response.data.tipoMensagem.mensagem});
      });
  }


  componentDidMount() {
    this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => this.setState({usuarios: res.data.lista})
      )]
    })
  }
  
  render() {
    
    componentDidMount() {
      this.setState({
        grupos: [ApiGrupoService.todos().then(
          res => this.setState({usuarios: res.data.lista})
        )]
      })
    }

    return (
      <div>
            <Growl ref={el => (this.growl = el)} />
            <h1>Grupo *</h1>
            <Dropdown value={this.usuario.grupo} options={this.state.grupos}
              onChange={(e) => {this.setState({grupo: e.value})}} 
              placeholder="Selecione o grupo"/>
            <h1>Nome *</h1>
            <InputText value={this.usuario.nome} 
                onChange={(e) => this.setState({nome: e.target.value})} /><br/>
            <h1>Sobrenome *</h1>
            <InputText value={this.usuario.sobrenome} 
                onChange={(e) => this.setState({sobrenome: e.target.value})} /><br/>
            <h1>Aniversário *</h1>
            <Calendar value={this.usuario.dataAniversario} dateFormat="dd/mm/yy"
                onChange={(e) => this.setState({dataAniversario: e.value})} /><br/>
            <Button onClick={this.salvarUsuario} label="Salvar" />
        </div>
    );
  }
}

export default UsuarioForm;

Está última dá erro de código no visual studio

erro

Mike

O componentDidMount é fora do render,

E ai tem uma coisa errada, você ta dando um setState dentro do setState

Você tentou com o código que postei?

guilhermebhte

Dá este erro e não vai no back end

Mike

Isso é pq você não criou o state no construtor

this.state = {
    grupos: {

    }
}
guilhermebhte

Agora deu este erro:

Mike

items é um array?

guilhermebhte

Entendo que itens, é o retorno do JSON do banco de dados

componentDidMount() {
    this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => {
          return res.data.lista;
        }
      )]
    })
  }

Dessa maneira retorna uma lista, mas continua dando o mesmo erro.

Mike

Você esta passando this.state.grupos na propriedade options do DropDown, talvez esse itens é a variável que é declarada internamente no DropDown e ai ela ta acusando que this.state.grupos não é um array (o erro .map is not a function acontece quando o a variavel que esta invocando a função map não é um array)

guilhermebhte

Tenho que fazer a conversão para map ?

Mike

Não, this.state.grupos tem que ser um array, você tem certeza que é?

Da um console.log nele e posta aqui.

Pra pegar o valor do estado logo após o setState, você tem que fazer que nem o código abaixo:

this.setState({
      grupos: [ApiGrupoService.todos().then(
        res => {
          return res.data.lista;
        }
      )]
    }, console.log("grupos", this.state.grupos));
guilhermebhte

o resp.data.lista é um array.

o this.state.grupos vem vazio

erro

Mike

Então é um array mesmo. Acho que ja sei o que é.

Falei para você deixar assim o código:

this.state = {
    grupos: {

    }
}

Mas na verdade, tem que ser assim:

this.state = {
    grupos: [

    ]
}

O grupos tem que ser um par de colchetes e não chaves.

Antes dessa requisição terminar, o render esta sendo executado, e ai o this.state.grupos ainda é um objeto, ai só quando a requisição termina, que ele vira um array populado, o certo é deixar ele como array inicialmente.

Ve ai

guilhermebhte

Vai no backend, mas não atualiza o componente.

Criado 4 de dezembro de 2019
Ultima resposta 5 de dez. de 2019
Respostas 16
Participantes 2