【问题标题】:How to make work search bar passing props through components?如何使工作搜索栏通过组件传递道具?
【发布时间】:2020-09-10 18:09:17
【问题描述】:

我想过滤数据并在搜索栏中实现。在 Hook/index.js 组件中,我在 useEffects 中获取和过滤数据。然后我在 App.js 中传递道具。之后我有一个 Searchbar 组件,我在其中收听输入,并且它必须在这里工作。我得到未定义

Hook/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


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]
}



搜索栏组件



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>
  );
};



【问题讨论】:

  • {/*this throws an error */} 你得到的错误是什么
  • 嘿@sgrmhdk 这里是错误:对象作为 React 子项无效(找到:对象与键 {name、topLevelDomain、alpha2Code、alpha3Code、callingCodes、capital、altSpellings、region、subregion、population , latlng, demoym, area, gini, timezones, 边界, nativeName, numericCode, 货币, 语言, 翻译, flag, regionBlocs, cioc})。如果您打算渲染一组子项,请改用数组。
  • 能不能把console.log(data)放到App.js里。只是为了确定是否填充了数据并查看对象的结构
  • 嘿 @sgrmhdk 如果我删除 data={data} 和 console.log(data) 给我控制台中的对象数组。

标签: javascript reactjs


【解决方案1】:

您将数据变量发送到输入而不是搜索变量。

在 JS 过滤器返回数组和 DOM 不能显示数组,因为它不是 html 或 jsx,所以你需要将数组转换为 jsx 与 map。使用 map 你可以返回数组或 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>

【讨论】:

【解决方案2】:

您的新.filter() 数组中包含对象!您需要在返回之前.map() 它,因为对象作为 React 子对象无效。


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

解释:

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*/} ];

当你返回array 时,React 拒绝挂载你的对象,因为它不知道该怎么做。这就是你映射它的原因,以访问其中的每个对象。

【讨论】:

  • 嘿@Iago Calazans 感谢您再次回复。但你是什么意思?我不明白。你能解释一下吗?
  • 好的@Greg我已经对上面的答案做出了解释!啊! ☑️
  • @Iago Calazans 非常感谢你,这是有道理的。我会再试一次。到目前为止没有成功
  • @Greg where i've set /* 你的代码放在这里 */,尝试用
    {element.name}
    覆盖并告诉我它是否有效。
  • 就是这样!看起来这个问题已经回答了,您应该将问题标题更改为“.filter() not working with React Child component”哈哈?。 useContext 将是您面临的另一个挑战,它的逻辑与您的 Hook 匿名函数非常接近。
猜你喜欢
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-21
  • 2019-02-14
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 2022-12-03
相关资源
最近更新 更多