EzJS
EzJS

Reputation: 229

Cannot read property of undefined React Hooks

I am trying to create a search feature using react hooks but it keeps returning the error:

Cannot read Property of Undefined

on the updateSearch function whenever I type in the input field.

  const [search, setSearch] = React.useState('');
  const [searchResults, setSearchResults] = React.useState([]);

  const [state, setState] = React.useState({
    open: false,
    name: '',
    users:[]
  });

  useEffect(() => {
    getAllUsers();
  }, []);


  const getAllUsers = () => {
    fetch('/userinformation/', { 
      method: 'GET',
      headers: {'Content-Type':'application/json'}
    })
    .then(function(response) {
      return response.json()
    }).then(function(body) {
      console.log(body);
      setState({...state, users: body });
    })
  }

  const updateSearch = (event) => {
   setSearch(event.target.value)
  }

  React.useEffect(() => {
    const results = state.users.filter(user =>
      user.toLowerCase().includes(search)
    );
    setSearchResults(results);
  }, [search]);

return (
<input type="text" value={search} onChange={(e) => updateSearch(e.target.value)}/>
)

Whenever I type in the search bar I get the following error: enter image description here

How can i fix this?

Upvotes: 4

Views: 16823

Answers (5)

barper
barper

Reputation: 109

For me changing from import React from 'react' and using state with React.useState() into import {useState} from 'react' and using it as useState() without the React namespace did the trick

Upvotes: 0

Jawad ul hassan
Jawad ul hassan

Reputation: 575

You can either get to the value of passed event by changing

<input type="text" value={search} onChange={(event) => updateSearch(event}/>

or you can keep the input element as it is and change the update updateSearch callback to

const updateSearch = (event) => { setSearch(event) }

Secondly, you are applying includes to a single item of an array which is specific to array methods, you need to make following changes as well to make it work:

React.useEffect(() => { 
 const results = state.users.filter( user => user.firstName.toLowerCase() === search ); 
 setSearchResults(results); 
}, [search])

Upvotes: 6

wentjun
wentjun

Reputation: 42526

You have already passed the value of the input into the updateSearch method.

This is how you should fix it:

const updateSearch = (value) => {
   setSearch(value);
};

And as for the second issue you have raised on your useEffect hook, you will have to call toLowerCase() on one of your properties (either firstName or lastName), depending on what you need to search for.

React.useEffect(() => {
  const results = state.users.filter(user =>
    user.firstName.toLowerCase().includes(search)
  );
  setSearchResults(results);
}, [search]);

Upvotes: 1

Tolumide
Tolumide

Reputation: 984

I would teach you a secret that has worked very well for me over the years. When javascript gives you such error as cannot read property ***whateverValue*** value of undefined it means you are trying to read the property of an object that does not exist. In this case, the object you're trying to read from is undefined, hence it cannot have any key: value pair.

Back to your question: TypeError: Cannot read property value of undefined

  1. Using cmd+f to check for all places where value is used shows me everywhere you used value on event.target.value

Stay with me (I know this is boring, but it would help later).

  1. You have an event handler named updateSearch.

  2. All you need here now is to change your input tag to this:

<input type="text" value={search} onChange={updateSearch}/> Don't worry, React would handle the rest, it automatically parses the event to eventHandler which can then be accessed on such eventHandler.

Also, I think you might want to refactor this component.

Something like import React, {useState, useEffect} from React you won't have to call React.useEffect or React.useState in other parts of the project. just useEffect or useState. Goodluck :+1

Upvotes: 0

uday
uday

Reputation: 1481

in your input you're already passing valueonChange={(e) => updateSearch(e.target.value) and in updateSearch you're trying to accessing it. Change it like this, if you want to access event in updateSearch method and get value from it.

<input type="text" value={search} onChange={(e) => updateSearch(e}/>

Upvotes: 1

Related Questions