使用先前输入的数据反应表单

React form using data from previous input

我正在使用 React 和天气 API 并整理了这个表格:

function Forecast() {
  const [cities, setCities] = React.useState([]);

  const addCity = (city) => {
    if (!city.text || /^\s*$/.test(city.text)) {
      return;
    }

    const newCities = [city, ...cities];

    setCities(newCities);
  };

  const removeCity = (id) => {
    const removedArray = [...cities].filter((city) => city.id !== id);

    setCities(removedArray);
  };

  return (
    <div>
      <Form onSubmit={addCity} />
    </div>
  );
}

const Form = (props) => {
  const api = {
    key: "39471307bd579e5ce6b1d89dc164dd77",
    base: "https://api.openweathermap.org/data/2.5/",
  };

  const [input, setInput] = React.useState("");
  const [weather, setWeather] = React.useState({});
  const [query, setQuery] = React.useState("");

  const handleChange = (e) => {
    setInput(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    fetch(`${api.base}weather?q=${input}&appid=${api.key}&units=metric`)
      .then((res) => res.json())
      .then((result) => setWeather(result));

    props.onSubmit({
      id: Math.floor(Math.random() * 10000),
      text: input,
      data: weather,
    });

    setInput("");
  };

  return (
    <form className="search-container" onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Enter City"
        name="text"
        value={input}
        className="search"
        onChange={handleChange}
      />
      <button className="add-card-button">
        <i className="fas fa-plus-circle"></i>
      </button>
    </form>
  );
};

ReactDOM.render(<Forecast />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

当我对此进行测试时,第一次搜索城市时它没有返回任何数据,第二次搜索时,它使用第一次搜索的输入,依此类推。有谁知道我怎样才能得到它以便立即搜索 returns 数据?

useRef 钩子适用于表单。为表单分配一个 useRef 挂钩变量

删除!!

  const [input, setInput] = React.useState("");

替换

const input = useRef('')

输入标签

 <input
    type="text"
    placeholder="Enter City"
    name="text"
    ref={input}
    className="search"
  />

提交函数

  const handleSubmit = (e) => {
e.preventDefault();

fetch(`${api.base}weather?q=${input.current.value}&appid=${api.key}&units=metric`)
  .then((res) => res.json())
  .then((result) => setWeather(result));

props.onSubmit({
  id: Math.floor(Math.random() * 10000),
  text: input.current.value,
  data: weather,
});

input.current.value = '';

};

我现在不会编码。但是尝试将提取放在 useEffect 挂钩中。并在提交后以某种方式触发效果。里面有条件什么的。也许将状态作为 useEffect 的依赖项传递。

也许明天我可以为你的代码发送一个合适的建议

fetch() 异步的 。您必须在 API 调用完成后 设置您的天气数据。

此外,您必须确保使用新鲜的 result(调用 setWeather(result) 不会立即更新 weather)。

handleSubmit 编辑为如下内容:

  const handleSubmit = (e) => {
    e.preventDefault();

    fetch(`${api.base}weather?q=${input}&appid=${api.key}&units=metric`)
      .then((res) => res.json())
      .then((result) => {
        props.onSubmit({
          id: Math.floor(Math.random() * 10000),
          text: input,
          data: result,
        });
        setWeather(result);
        setInput("");
      });
  };

资源:

  • How to return the response from an asynchronous call?

完整代码:

function Forecast() {
  const [cities, setCities] = React.useState([]);

  const addCity = (city) => {
    if (!city.text || /^\s*$/.test(city.text)) {
      return;
    }

    const newCities = [city, ...cities];
    console.log(newCities);
    setCities(newCities);
  };

  const removeCity = (id) => {
    const removedArray = [...cities].filter((city) => city.id !== id);

    setCities(removedArray);
  };

  return (
    <div>
      <Form onSubmit={addCity} />
    </div>
  );
}

const Form = (props) => {
  const api = {
    key: "39471307bd579e5ce6b1d89dc164dd77",
    base: "https://api.openweathermap.org/data/2.5/",
  };

  const [input, setInput] = React.useState("");
  const [weather, setWeather] = React.useState({});
  const [query, setQuery] = React.useState("");

  const handleChange = (e) => {
    setInput(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    fetch(`${api.base}weather?q=${input}&appid=${api.key}&units=metric`)
      .then((res) => res.json())
      .then((result) => {
        props.onSubmit({
          id: Math.floor(Math.random() * 10000),
          text: input,
          data: result,
        });
        setWeather(result);
        setInput("");
      });
  };

  return (
    <form className="search-container" onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Enter City"
        name="text"
        value={input}
        className="search"
        onChange={handleChange}
      />
      <button className="add-card-button">
        <i className="fas fa-plus-circle"></i>
      </button>
    </form>
  );
};

ReactDOM.render(<Forecast />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>