最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Uncaught TypeError: Cannot read property 'filter' of undefined React - Stack Overflow

programmeradmin7浏览0评论

I have a simple react app, which I am using to display a list of users. I have a search box, which filters the list of users and returns the searched user,

However, When I search for users using the search box, I get a TypeError: Cannot read property 'filter' of undefined

The page initially displays fine, it just when I search for the users that the error is thrown. I know the users are being generated correctly because I console logged filteredUsers The users are all outputted correctly.

Here is my App.js

import { useState } from 'react';
import React from 'react';
import CardList from './ponents/CardList';
import SearchBox from './ponents/SearchBox';
import { users } from './users';
import 'tachyons';

const App = () => {
  const [state, setState] = useState({
    users,
    searchField: '',
  });

  const filteredUsers = state.users.filter((user) => {
    return user.name.toLowerCase().includes(state.searchField.toLowerCase());
  });

  const onSearchChange = (e) => {
    setState({ searchField: e.target.value });
  };

  return (
    <div className='App tc'>
      <h1>RoboFriends</h1>
      <SearchBox searchChange={onSearchChange} />
      <CardList robots={filteredUsers} />
    </div>
  );
};

export default App;

and here is my SearchBox.js

import React from 'react';

const SearchBox = ({ searchField, searchChange }) => {
  return (
    <div className='pa2'>
      <input
        className='pa3 ba b--green bg-lightest-blue'
        type='search'
        placeholder='Search Users'
        onChange={searchChange}
      />
    </div>
  );
};

export default SearchBox;

I have a simple react app, which I am using to display a list of users. I have a search box, which filters the list of users and returns the searched user,

However, When I search for users using the search box, I get a TypeError: Cannot read property 'filter' of undefined

The page initially displays fine, it just when I search for the users that the error is thrown. I know the users are being generated correctly because I console logged filteredUsers The users are all outputted correctly.

Here is my App.js

import { useState } from 'react';
import React from 'react';
import CardList from './ponents/CardList';
import SearchBox from './ponents/SearchBox';
import { users } from './users';
import 'tachyons';

const App = () => {
  const [state, setState] = useState({
    users,
    searchField: '',
  });

  const filteredUsers = state.users.filter((user) => {
    return user.name.toLowerCase().includes(state.searchField.toLowerCase());
  });

  const onSearchChange = (e) => {
    setState({ searchField: e.target.value });
  };

  return (
    <div className='App tc'>
      <h1>RoboFriends</h1>
      <SearchBox searchChange={onSearchChange} />
      <CardList robots={filteredUsers} />
    </div>
  );
};

export default App;

and here is my SearchBox.js

import React from 'react';

const SearchBox = ({ searchField, searchChange }) => {
  return (
    <div className='pa2'>
      <input
        className='pa3 ba b--green bg-lightest-blue'
        type='search'
        placeholder='Search Users'
        onChange={searchChange}
      />
    </div>
  );
};

export default SearchBox;
Share Improve this question asked Feb 9, 2021 at 9:49 user6248190user6248190 1,2692 gold badges20 silver badges36 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

Because you are using state.users here, filter expect it to be an array.

  const filteredUsers = state.users.filter((user) => {
    return user.name.toLowerCase().includes(state.searchField.toLowerCase());
  });

so you need to set the initial state as an array

 const [state, setState] = useState({
    users: [], //or a initial value of array of users.
    searchField: '',
  });

You also need to retain the users when you update the state.

  const onSearchChange = (e) => {
    setState( prev => ({ ...prev, searchField: e.target.value }));
  };

  //OR 

  const onSearchChange = (e) => {
    setState({ ...state, searchField: e.target.value });
  };

However, this line is not good because it's being called on every render, you should probably "upgrade" it with useMemo like this.

 const filteredUsers = useMemo(() => state.users.filter((user) => {
    return user.name.toLowerCase().includes(state.searchField.toLowerCase());
  }), [state])

Change

  const onSearchChange = (e) => {
    setState({ searchField: e.target.value });
  };

to

const onSearchChange = (e) => {
        setState({ searchField: e.target.name.value });
      };

And make users into an array

发布评论

评论列表(0)

  1. 暂无评论