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

Bind e Arrow Function

Estou lendo um livro chamado "The Road to Learn React'' para me aprofundar melhor no assunto e no mesmo mostra como se cria um search filter. Contudo, eu não consigo realizar o procedimento utilizando arrow function, como mostrado abaixo:

const isSearched = searchTerm => item => item.title.toLowerCase().includes(searchTerm.toLowerCase())

class App extends Component {

  list = [
    {
      title: 'React',
      url: 'https://facebook.github.io/react/',
      author: 'Jordan Walke',
      num_comments: 3,
      points: 4,
      objectID: 0,
    },
    {
      title: 'Redux',
      url: 'https://github.com/reactjs/redux',
      author: 'Dan Abramov, Andrew Clark',
      num_comments: 2,
      points: 5,
      objectID: 1,
    },
    { title: 'JS',
      url: 'https://github.com/reactjs/redux',
      author: 'Thales',
      num_comments: 2,
      points: 5,
      objectID: 2,
    }
  ];

  constructor(props){
    super(props)

    this.state = {
      lista: this.list,
      searchTerm: '',
    }

  }

  onDimiss(id){
    this.setState({lista: this.state.lista.filter(item => item.objectID !== id)})
  }

  onSearchChange(e){
    this.setState({searchTerm: e.target.value})
  }

  render(){
    return(
      <div>
        <form>
          <input type="text" onChange={() => this.onSearchChange}/>
        </form>
...

Logo, consigo realizar utilizando-se do bind:

const isSearched = searchTerm => item => item.title.toLowerCase().includes(searchTerm.toLowerCase())

class App extends Component {

  list = [
    {
      title: 'React',
      url: 'https://facebook.github.io/react/',
      author: 'Jordan Walke',
      num_comments: 3,
      points: 4,
      objectID: 0,
    },
    {
      title: 'Redux',
      url: 'https://github.com/reactjs/redux',
      author: 'Dan Abramov, Andrew Clark',
      num_comments: 2,
      points: 5,
      objectID: 1,
    },
    { title: 'JS',
      url: 'https://github.com/reactjs/redux',
      author: 'Thales',
      num_comments: 2,
      points: 5,
      objectID: 2,
    }
  ];

  constructor(props){
    super(props)

    this.state = {
      lista: this.list,
      searchTerm: '',
    }

    this.onSearchChange = this.onSearchChange.bind(this)
  }

  onDimiss(id){
    this.setState({lista: this.state.lista.filter(item => item.objectID !== id)})
  }

  onSearchChange(e){
    this.setState({searchTerm: e.target.value})
  }

  render(){
    return(
      <div>
        <form>
          <input type="text" onChange={this.onSearchChange}/>
        </form>
...

Alguém pode me explicar o motivo disso ocorrer?

Desde já, agradeço a atenção!

3 respostas
solução!

Fala aí Thales, tudo bem? Isso ocorre por conta do contexto de execução quando usamos function e quando usamos arrow function.

  • function: Seu contexto será onde a mesma foi executada, nesse caso, o this, pode ter N valores, vai depender de quem e onde ela foi chamada.
  • arrow function: Possuí o contexto de onde foi criada, nesse caso não importa onde você chamar, o contexto de this será onde ela foi criada (por padrão).

Sua função onSearchChange é uma função normal, e quem vai executar ela será o browser, logo, o this será undefined pois ele pode ser N coisas.

Quando você faz o bind(this), você está dizendo que o contexto dela deve ser o this, no caso o componente. Então o this dentro da função será o seu componente.

Se você quiser evitar o uso do bind(this), troca ela para arrow function:

onSearchChange = (e) => this.setState({searchTerm: e.target.value})

A mesma deve funcionar corretamente, sem a necessidade do bind.

Espero ter ajudado.

Muito obrigado pela ajuda!

Magina Thales, sempre que precisar não deixe de criar suas dúvidas.

Abraços e bons estudos.