React Hook для поиска пользователя - PullRequest
1 голос
/ 30 мая 2020

Я пытаюсь использовать React useState Hook для онлайн-проекта. Я хочу, чтобы когда я набирал имя пользователя в поле поиска, он находил карточку пользователя в браузере. Я могу зарегистрировать пользователя на консоли, но я не могу понять, как заставить его отобразить на экране. Столько способов перепробовал и просто не понял.

вывод консоли

Приложение. js

import React, { useState } from 'react';
import CardList from './CardList';
import {robots} from './robots';
import SearchBox from './SearchBox';


function App() {

  let [searchInput] = useState('');

  function onSearchChange(e) {

    searchInput = e.target.value;

    const filteredRobots = robots.filter(function(robot){
      return robot.name.toLowerCase().includes(searchInput.toLowerCase());
    });

    console.log(filteredRobots);

  }



  return (
    <div className='tc'>
      <h1>RoboFriends</h1>
      <SearchBox searchChange={onSearchChange} />
      <CardList id={robots.id} name={robots.name} email={robots.email}/>
    </div>
  );
}

export default App;

CardList. js

import React from 'react';
import Card from './Card';
import {robots} from './robots';

function CardList(props) {
  return (
    <div>
    {
      robots.map(function(user) {
        return <Card key={user.id} id={user.id} name={user.name} email={user.email} />
      })
    };
  </div> )
}

export default CardList;

Card. js

import React from 'react';
import 'tachyons';


function Card(props) {
  return (
    <div className='bg-light-green dib br3 pa3 ma2 grow shadow-5'>
      <img src={`https://robohash.org/${props.id}`} alt="Robot" />
      <h2>{props.name}</h2>
      <p>{props.email}</p>
    </div>
  );
}

export default Card;

Ответы [ 3 ]

2 голосов
/ 30 мая 2020

React только повторно отображает, когда вы устанавливаете состояние на новое значение.

Проверьте код ниже:

import React, { useState } from 'react';
import CardList from './CardList';
import {robots} from './robots';
import SearchBox from './SearchBox';


function App() {

  let [searchInput, setSeachInput] = useState('');

  function onSearchChange(e) {
    
    // set state here to re-render
    setSeachInput(e.target.value);
  }

  // use might want to use useMemo to improve this, I just want to make it simple now
   const filteredRobots = robots.filter(function(robot){
      return robot.name.toLowerCase().includes(searchInput.toLowerCase());
    });

    console.log(filteredRobots);


  return (
    <div className='tc'>
      <h1>RoboFriends</h1>
      <SearchBox searchChange={onSearchChange} />
      {/* using filteredRobots herer*/}
      <CardList id={filteredRobots.id} name={filteredRobots.name} email={filteredRobots.email}/>
    </div>
  );
}

export default App;
1 голос
/ 30 мая 2020

Вы не должны изменять значение searchInput как searchInput = e.target.value. Для обновления значения лучше вызвать функцию установки. Например,

const [searchInput, setSearchInput] = useState('');

// to update the value of searchInput call setSearchInput
function onSearchChange(e) {
    setSearchInput(e.target.value)
}

Изменения состояния асинхронны. Когда вы пытаетесь отфильтровать robots, не гарантируется, что он будет вызван с последним значением searchInput, поэтому вы должны использовать useEffect хук, который будет фильтровать роботов при изменении значения searchInput.

Вот решение,

import React, { useState } from 'react';
import CardList from './CardList';
import {robots} from './robots';
import SearchBox from './SearchBox';


function App() {

  let [searchInput, setSearchInput] = useState('');
  let [filterdRobots, setFilteredRobots] = useState(robots);

  function onSearchChange(e) {
    setSearchInput(e.target.value);
  }

  useEffect(() => {
     setFilteredRobots(robots.filter(r =>
       r.name.toLowerCase().includes(searchInput.toLowerCase())))
  }, [searchInput, robots])



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

export default App;

проверьте codeanbox для демонстрации

1 голос
/ 30 мая 2020

В вашем приложении. js файл searchInput не устанавливается в состояние

import React, { useState } from 'react';
import CardList from './CardList';
import {robots} from './robots';
import SearchBox from './SearchBox';


function App() {

  let [searchInput, setSearchInput] = useState('');

  function onSearchChange(e) {
    setSearchInput(e.target.value)   

  }
    **You can pass the filterRobots in place of robots to get only words passed in the search box**


 const filteredRobots = robots.filter(function(robot){
      return robot.name.toLowerCase().includes(searchInput.toLowerCase());
    });



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

export default App;

В файле CardList

import React from 'react';
import Card from './Card';


 function CardList({robots}) {
  {
    robots.map((user, i) => {
      return (
        <Card
          key={i}
          id={user[i].id}
          name={user[i].name}
          email={user[i].email}
          />
      );
    })
  }
}

export default CardList;
...