使用来自先前输入的数据反应表单
Posted
技术标签:
【中文标题】使用来自先前输入的数据反应表单【英文标题】:React form using data from previous input 【发布时间】:2021-09-10 06:05:39 【问题描述】:我正在使用 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.baseweather?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>
当我对此进行测试时,第一次搜索城市时它不会返回任何数据,而第二次搜索时,它会使用第一次搜索的输入,依此类推。有谁知道我怎样才能得到它,以便第一次搜索立即返回数据?
【问题讨论】:
【参考方案1】:fetch()
是异步的。您必须在 API 调用完成后设置天气数据。。
此外,您必须确保使用新的result
(调用setWeather(result)
不会立即更新weather
)。
将handleSubmit
编辑成如下内容:
const handleSubmit = (e) =>
e.preventDefault();
fetch(`$api.baseweather?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? useState set method not reflecting change immediately完整代码:
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.baseweather?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>
【讨论】:
【参考方案2】: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.baseweather?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 = '';
;
【讨论】:
你刚刚用一个 ref 替换了一个正常的状态变量,这完全没有解决任何问题。你还没有解释你的方法。您的代码块没有正确缩进。【参考方案3】:我现在不会编码。但是尝试将 fetch 放在 useEffect 挂钩中。并在提交后以某种方式触发效果。里面有条件或其他东西。也许将状态作为 useEffect 的依赖项传递。
也许明天我可以为您的代码发送适当的建议
【讨论】:
这不是问题所在。handleSubmit()
(和 fetch()
依次)确实在提交表单时被调用。以上是关于使用来自先前输入的数据反应表单的主要内容,如果未能解决你的问题,请参考以下文章
angular 7 反应式表单:为表单中的每个输入字段动态添加/删除输入字段