我正在创建一个搜索栏,它调用 API 以返回具有匹配名称的设备列表。 理想情况下,当用户第一次查看组件时,它只看到一个搜索栏。用户在搜索栏中键入内容后,API 将返回匹配名称的列表。然后,这些名称的列表将显示在搜索栏下方。
我正在尝试使用钩子执行此操作,但是我无法显示列表/要更新的组件并显示新列表。
我错过了什么,这是正确的方法吗?
const Search = () => {
const [input, setInput] = useState("");
let devices = [];
const handleChange = e => {
setInput(e.target.value.toUpperCase());
};
useEffect(() => {
apiService.getDevices(input).then(response => {
console.log("response:", response); // This brings back the response correctly
const newDevices = response.map(device => <li key={device}>{device}</li>);
devices = <ul>{newDevices}</ul>;
});
}, [input]);
return (
<Fragment>
<div>
<div className="form-group">
<div className="form-group__text">
<input
type="search"
onChange={handleChange}
placeholder="Search device by serial number"
/>
<button type="button" className="link" tabIndex="-1">
<span className="icon-search"></span>
</button>
</div>
</div>
<div>{devices}</div>
<p>testestes</p>
</div>
</Fragment>
);
};
将设备存储在状态中,然后直接在返回中执行映射渲染,如下所示:
const Search = () => {
const [input, setInput] = useState("");
const [devices, setDevices] = useState([]);
const handleChange = e => {
setInput(e.target.value.toUpperCase());
};
useEffect(() => {
apiService.getDevices(input).then(response => {
setDevices(response);
});
}, [input]);
return (
<Fragment>
<div>
<div className="form-group">
<div className="form-group__text">
<input
type="search"
onChange={handleChange}
placeholder="Search device by serial number"
/>
<button type="button" className="link" tabIndex="-1">
<span className="icon-search"></span>
</button>
</div>
</div>
<div>
<ul>
{devices.map(device => <li key={device}>{device}</li>)}
</ul>
</div>
<p>testestes</p>
</div>
</Fragment>
);
};
组件只会在 props 或状态更改时重新渲染,因此useEffect
无法在不更新某些状态的情况下触发重新渲染