Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

CampoTexto: "props.aoAlterado is not a function"

Alguém poderia me explicar com calma sobre esse erro, por favor?

Erro no console do navegador

O código utilizado na aula: https://github.com/alura-cursos/organo/blob/aula-3/src/componentes/CampoTexto/index.js

import './CampoTexto.css'

const CampoTexto = (props) => {

    const placeholderModificada = `${props.placeholder}...` 

    const aoDigitado = (evento) => {
        props.aoAlterado(evento.target.value)
    }

    return (
        <div className="campo-texto">
            <label>
                {props.label}
            </label>
            <input value={props.valor} onChange={aoDigitado} required={props.obrigatorio} placeholder={placeholderModificada}/>
        </div>
    )
}

export default CampoTexto

O meu código:

import './TextField.css'

const TextField = (props) => {
  const placeholderText = `${props.placeholder}`

  const handleChange = (event) => {
    props.onChange(event.target.value)
  }

  return (
    <div className='text-field'>
      <label>{props.label}</label>
      <input
        value={props.value}
        onChange={handleChange}
        required={props.required}
        placeholder={placeholderText}
      />
    </div>
  )
}

export default TextField
5 respostas

Olá!

Consegue compartilhar a forma com que você utilizou o componente?

Da forma que você fez, ele espera uma função via prop chamada onChange, mais ou menos assim:

const [texto, setTexto] = useState('');

<TextField value={texto} onChange={value => setTexto(value)} />

Se você não passar a função no onChange vai ter esse erro, porque o componente espera uma função e não recebeu nada.

Então... Mas fiquei confuso com essa recomendação... No código utilizado (no vídeo e no github) não tem nenhum useState no component CampoTexto e não tem um useState específico pro texto ([texto, setTexto] = useState('')) no component Formulario

E, no meu código, o component está sendo utilizado da seguinte maneira:

import { useState } from 'react'
import Button from '../Button/Button.js'
import Dropdown from '../Dropdown/Dropdown.js'
import TextField from '../TextField/TextField.js'
import './Form.css'

const Form = (props) => {
  const squads = [
    'Programação',
    'Front-End',
    'Data Science',
    'DevOps',
    'UX e Design',
    'Mobile',
    'Inovação e Gestão',
  ]

  const [name, setName] = useState('')
  const [role, setRole] = useState('')
  const [image, setImage] = useState('')
  const [squad, setSquad] = useState('')

  const onSave = (event) => {
    event.preventDefault()
    console.log('Dados salvos: ', name, role, image)
    props.onMemberRegister({
      name,
      role,
      image,
      squad,
    })
  }

  return (
    <section className='form'>
      <form onSubmit={onSave}>
        <h2>Preencha os dados para criar o card do colaborador</h2>
        <TextField
          required={true}
          label='Nome'
          placeholder='Digite seu nome'
          value={name}
          handleChange={(value) => setName(value)}
        />
        <TextField
          required={true}
          label='Cargo'
          placeholder='Digite seu cargo'
          value={role}
          handleChange={(value) => setRole(value)}
        />
        <TextField
          label='Imagem'
          placeholder='Informe o endereço da imagem'
          value={image}
          handleChange={(value) => setImage(value)}
        />
        <Dropdown
          required={true}
          label='Times'
          itens={squads}
          value={squad}
          handleChange={(value) => setSquad(value)}
        />
        <Button>Criar Card</Button>
      </form>
    </section>
  )
}

export default Form

Você precisa ajustar o nome da prop do seu TextField:

Ao invés de:

<TextField
          label='Imagem'
          placeholder='Informe o endereço da imagem'
          value={image}
          handleChange={(value) => setImage(value)}
/>

Você precisa de:

<TextField
          label='Imagem'
          placeholder='Informe o endereço da imagem'
          value={image}
          onChange={(value) => setImage(value)}
/>

Porque dentro do componente você faz:

    props.onChange(event.target.value)

Percebeu a diferença? E durante o curso a gente vai passar a controlar o estado do formulário na aula 3 :)

Ah, entendi!

Mas aí me surgiram algumas dúvidas:

1) O mais indicado seria inverter os nomes para manter a prop como handleChange, não é?

2) E o problema é que, ao fazer isso, a função passa a se chamar onChange, sendo que onChange já é uma função do próprio React, certo?

3) Como seria a partir daí, seguindo boas práticas? O ideal seria dar outro nome para a função seguindo algum padrão pré-estabelecido, como handleChange, onSave, etc?

solução!

1 - As nomeclatura dos métodos, idealmente, segue um padrão. Isso varia de projeto a projeto, empresa a empresa. Eu, pessoalmente falando, utilizaria o nome onChange.

2 - Não é uma função do React, mas sim um eventos de elementos no DOM. Dá uma olhada nesse link aqui pra entender melhor de onde vem o onChange e quando ele é utilizado.

3 - Vale a pena buscar uma convenção e seguí-la, Como, por exemplo, essa aqui do AirBnB que é muito famosa.

Excelentes perguntas!

Bons estudos ;)