简体   繁体   English

如何让工作搜索栏通过组件传递道具?

[英]How to make work search bar passing props through components?

I want to filter data and implement in search bar.我想过滤数据并在搜索栏中实现。 In Hook/index.js component I am fetching and filtering data inside useEffects .Hook/index.js组件中,我在useEffects 中获取和过滤数据。 Then I am passing props in App.js .然后我在App.js 中传递道具。 Afterwards I have a Searchbar component, where I am listening to the input and here it must work.之后我有一个Searchbar组件,我在那里听输入,在这里它必须工作。 I get undefined .我得到undefined

Hook/index.js component钩子/index.js组件


import React, { useState, useEffect } from "react";

import "./hook.scss";

export default () => {
  const [data, setData] = useState([]);
  const [error, setError] = useState(null);
  const [search, setSearch] = useState("");

  const fetchData = () => {
    fetch("https://restcountries.eu/rest/v2/all")
      .then((res) => res.json())
      .then((result) => setData(result))
      .catch((err) => console.log("error"));
  };

  useEffect(() => {
    const searchResult =
      data && data.filter((item) => item.name.toLowerCase().includes(search));
    setSearch(searchResult);
  }, []);

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

  return [data, error];
};

App.js应用程序.js


import React, { useState }from "react";
import Header from "./components/Header";
import SearchBar from "./components/SearchBar";
import Flag from "./components/Flag";
import useCountries from "./Hooks";
import CountryList from "./components/CountryList";



import "./App.scss";

export default function App()  {
  const [data, error] = useCountries();

  
  return (
    <div className="App">
      <SearchBar />  //   {/*this throws an error <SearchBar data={data}/> */}
      <Header />
      {data &&
        data.map((country) => (
          <div className="CountryList" key={country.name}>
            <Flag flag={country.flag} />
            <CountryList
              population={country.population}
              name={country.name}
              region={country.region}
            />
            {country.languages.map((language, languageIndex) => (
              <CountryList key={languageIndex} language={language.name} />
            ))}
           
          </div>
        ))}
      <useCountries />
    </div>
  );
  return [data, error]
}



Searchbar component搜索栏组件



import React, {useState} from "react";


import "./SearchBar.scss";

export default function SearchBar({data}) {
    const [search, setSearch] = useState("");

   function handleChange(e) {
    setSearch(e.target.value);
  } 
  return (
    <div className="SearchBar">
      <input
        className="input"
        type="text"
        placeholder="search country ..."
        value={data}
        onChange={handleChange}
      />

      {data && data.filter((item) => item.name.toLowerCase().includes(search))}
    </div>
  );
};



You are sending data variable to input instead of search variable.您将数据变量发送到输入而不是搜索变量。

In JS filter return array and DOM cannot display array since it is not html or jsx so you need to convert array to jsx with map.在 JS 过滤器中返回数组和 DOM 无法显示数组,因为它不是 html 或 jsx,因此您需要使用 map 将数组转换为 jsx。 with map you can return array or jsx使用地图,您可以返回数组或 jsx

   <div className="SearchBar">
        <input
           className="input"
           type="text"
           placeholder="search country ..."
           value={search} // change here 
           onChange={handleChange}
     />
     <ul>{(data || []).filter((item) => item.name.toLowerCase().includes(search)).map(e=>(<li key={e.name}>{e.name}</li>))}</ul> /change here
    </div>

Your new .filter() Array contains Objects inside it!您的新.filter()数组在其中包含对象! You need to .map() it before return as Objects are not valid as a React child.您需要在返回之前.map()它,因为对象作为 React 子对象无效。


{ data?.filter((item) => item.name.toLowerCase().includes(search)).map((element => 
<>
 /* Your code goes here! */
</>) }

Explanation:解释:

Array.prototype.filter() returns a new Array and in your case your Array is filled with Objects, like this: Array.prototype.filter()返回一个新数组,在您的情况下,您的数组充满了对象,如下所示:


{data && data.filter((item) => item.name.toLowerCase().includes(search))}
// The code above returns an Array just like below.

const array = [ {name: 'Brazil' /*...others properties*/}, {name: 'USA' /*...others properties*/}, {name: 'England' /*...others properties*/} ];

When you return array , React reject to mount your Objects, cus it can't understand what to do.当您返回array ,React 拒绝挂载您的对象,因为它无法理解该做什么。 That's why you map it, to have access to each Object inside it.这就是您映射它的原因,以访问其中的每个对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM