2
respostas

Função passada como prop está com o contexto errado

Após mover as funções criarNota e criarCategoria para dentro das classes de dados, ao passar elas como props o contexto está ficando errado.

App.js

import React, { Component } from 'react'
import Categories from './models/Categories'
import Notes from './models/Notes'
import NotesList from './components/notes/List'
import NotesForm from './components/notes/Form'
import CategoriesList from './components/categories/List'
import './assets/index.css'
import './assets/App.css'

class App extends Component {
  constructor() {
    super()
    this.categories = new Categories()
    this.notes = new Notes()
  }

  render() {
    return (
      <section className='content'>
        <NotesForm 
          createNote={this.notes.createNote} 
          categories={this.categories.items} 
        />

        <main className='main-content'>
          <CategoriesList 
            createCategory={this.categories.createCategory}
            categories={this.categories.items} 
          />

          <NotesList
            deleteNote={this.notes.deleteNote}
            notes={this.notes.items}
          />
        </main>
      </section>
    );
  }
}

export default App;

ListaDeCategorias.js

import React, { Component } from 'react'
import './style.css'

class List extends Component {
    _handleKeyUp(event) {
        if(event.key === 'Enter') {
            let name = event.target.value
            this.props.createCategory(name)
        }
    }

    render() {
        return (
            <section className='categories-list'>
                <ul className='categories-list_list'>
                    {this.props.categories.map((category, index) => {
                        return(
                            <li className='categories-list_item' key={index}>
                                {category}
                            </li>
                        )
                    })}
                </ul>
                <input 
                    className='categories-list_input'
                    type='text' 
                    placeholder='Adicionar categoria'
                    onKeyUp={this._handleKeyUp.bind(this)}
                />
            </section>
        );
    }
}

export default List;

Categorias.js

class Categories {
    constructor() {
        this.items = []
    }

    createCategory(name) {
        console.log(this)
        this.items.push(name)
    }
}

export default Categories

O console.log dentro da função createCategory está retornando o próprio obejto props, o que me leva a crer que o contexto foi passado errado.

categories: []
createCategory: ƒ createCategory(name)

Por conta disso, ao tentar chamar o .push ocorre o seguinte erro: TypeError: Cannot read property 'push' of undefined

Porém, comparando com o código da aula, me parece tudo OK. Onde estaria o erro?

2 respostas

Consegui fazer funcionar alterando o constructor da classe Categories:

Categories.js

class Categories {
    constructor() {
        this.items = []
        this.createCategory = this.createCategory.bind(this)
    }

    createCategory(name) {
        this.items.push(name)
    }
}

export default Categories

Essa seria a melhor forma de resolver mesmo?

Fala ai Paulo, tudo bem? Fico feliz que tenha resolvido o problema, o bind seria uma das formas de resolver esse problema de contexto, uma outra forma seria mudar sua função de expressão para arrow function, algo assim:

// expression function
createCategory(name) {
    this.items.push(name)
}

// arrow function
createCategory = (name) => {
    this.items.push(name)
}

Dessa forma não seria necessário o uso das arrow functions.

Espero ter ajudado.