【问题标题】:React field onChange not firing when value gets inserted programatically (hooks, not classes)以编程方式插入值时反应字段 onChange 不会触发(钩子,而不是类)
【发布时间】:2020-06-02 17:39:30
【问题描述】:


我正在编写一个应用程序(从全栈打开),它将搜索国家,如果只选择一个国家,则显示国家信息。 该应用程序在人类使用时运行良好,但是,如果显示超过 1 个国家/地区,我希望用户能够单击国家名称旁边的“显示”按钮,并显示给定国家/地区的国家信息。

我想我可以创建一个函数来更改搜索字段的值,并将该值设置为给定国家/地区的名称。
我的问题是,输入上的 onChange 在以编程方式填写时不会触发。

我尝试为输入字段创建一个新的钩子,但我也无法让它工作。 当以编程方式填充该字段时,如何触发我的 onChange 触发器?

我想在函数toggleShowCountry中做到这一点

代码:


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

import axios from 'axios';


function App() {

  const [countries, setCountries] = useState([]);
  const [search, setSearch] = useState(countries);
  const [inputField, setInputField] = useState("");

  const fetchCountries = () => {
    axios 
    .get('https://restcountries.eu/rest/v2/all')
    .then(response => {
      setCountries(response.data);
    });
  };
  useEffect(fetchCountries, []);

  const handleSearch = (e) => {
    e.preventDefault();
    const searchField = document.querySelector('#searchCountry').value;

      setSearch(Object.values(countries).filter(country => 
        country.name.toLowerCase().includes(searchField.toLowerCase())))

  }

  const toggleShowCountry = (props) => {

    const searchField = document.querySelector('#searchCountry');
    searchField.value = props;

  }

  return (
    <div>
      <h2>Search countries</h2>
      <Search handleSearch={handleSearch} />
      <Display countries={search} toggleShowCountry={toggleShowCountry} />
    </div>
  )
}

const Display = (props) => {

  const countries = props.countries;
  let filteredCountries = countries.map(country => country);

  if (countries.length > 10){
    return(
      <>
        <p>Too many matches, specify another filter.</p>
      </>
    )
  } else if (countries.length === 1){
    return (
      <>
      {filteredCountries.map(country =>
        <div key={country}>
          <ShowCountry country={country} key={country} />

        </div>
      )}

      </>
    )
  } else {
    return (
      <>

        {filteredCountries.map(country =>
          <ul key={country.name}>
            <FilteredCountries country={country} key={country.name} toggleShowCountry={props.toggleShowCountry}/>
          </ul>
        )}
      </>
    )
  }
}

const FilteredCountries = (props) => {
  const country = props.country;
  return (
    <>
      <li>{country.name} <button onClick={() => props.toggleShowCountry(country.name)}>Show</button></li>
    </>
  )
}

const ShowCountry = ({country}) => {

  return (
    <>
      <h2>{country.name}</h2>
      <p>Capital: {country.capital}</p>
      <p>Population: {country.population}</p>

      <h3><strong>Languages</strong></h3>
      <ul>
        {country.languages.map(language => 
          <li key={language.name}>{language.name}</li>
        )}
      </ul>
      <img src={country.flag} alt="flag" width="100px"/>
    </>
  )
}

const Search = (props) => {
  return (
    <div>
      <form>
        <div>
          <label htmlFor="countries">Enter country </label>
          <input name="countries" id="searchCountry" onChange={props.handleSearch} />
        </div> 
      </form>
    </div>
  )
}


export default App;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    输入onChange 事件处理程序只有在输入失去焦点时才会被调用,这意味着它不会被调用,除非你强制输入失去焦点或手动调用 onChange 结果。就像丹尼斯·斯图卡洛夫展示的那样。 :)

    【讨论】:

      【解决方案2】:

      你也可以调用 setSearch 然后它工作:

      const toggleShowCountry = (props) => {
        const searchField = document.querySelector('#searchCountry');
        searchField.value = props;
        setSearch(Object.values(countries).filter(country => 
          country.name.toLowerCase() === props.toLowerCase()))
      }
      

      在操场上查看:https://jscomplete.com/playground/s505973

      【讨论】:

      • 天哪!我不敢相信我是如此接近解决方案,但没有看到它。我想我太在意改变字段值了。找到解决方案的工作很棒。它完美地工作。谢谢。
      猜你喜欢
      • 2019-12-31
      • 1970-01-01
      • 2017-10-08
      • 2022-11-12
      • 1970-01-01
      • 2016-12-04
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多