import stores from './stores' // 事先准备好的接口库
import _ from 'loadsh'; // 使用 debounce,实时获得接口须要 debounce
class Search extend Component{
featchList = async (val = '')=>{
try{
const data = await stores.featchList(val);
data && this.setState({
data
})
}catch(err){
throw(err)
}
}
handleOnSearch = (ev)=>{
console.log(ev);
this.featchList(ev.target.value)
}
componentDidMount(){
this.featchList();
}
render(){
<div className="search-container">
<input onChange={_.debounce(ev => this.handleOnSearch(ev), 300)}/> <div className="list"> {this.state.data} </div> </div>
}
}
复制代码
如上一个简单的实时输入搜索,而后300ms延时展现结果的react就完成了,咱们怎么使用 hooks 改装一下啦?html
cakkBackFunc 能够返回一个函数,用做清理
array(可选参数):数组,用于控制useEffect的执行
* 分三种状况
《1》空数组,则只会执行一次(即初次渲染render),至关于componentDidMount
《2》非空数组,useEffect会在数组发生变化后执行
《3》不填array这个数组,useEffect每次渲染都会执行
复制代码
function App() {
const [data, setData] = useState([]);
const [query, setQuery] = useState('');
useEffect(() => {
const featchList = async (query = '')=>{
try{
const data = await stores.featchList(query);
data && setData(data);
}catch(err){
throw err;
}
}
featchList(query); // 咱们把 query 当作参数传进去,把data和query 联动起来这样就能够达到搜索的功能啦。
}, []);
return (
<div className="search-container"> <input onChange={_.debounce(ev => setQuery(ev.target.value), 300)}/> <div className="list"> {this.state.data} </div> </div> ); } export default App; 复制代码
咱们提供了一个 `exhaustive-deps ESLint` 规则做为 `eslint-plugin-react-hooks`
包的一部分。它会帮助你找出没法一致地处理更新的组件。
复制代码
试试上面的代码,发现如今只实现了 componentDidMount 中一次 mount的数据获取,咱们在输入 input 框的时候并无去请求新的数据,这个时候咱们就须要在 useEffect(a,b) 的第二个参数中放入 [query],当他发生变化的时候再从新触发 useEffect()react
function App() {
const [data, setData] = useState([]);
const [query, setQuery] = useState('');
useEffect(() => {
const featchList = async (query = '')=>{
try{
const data = await stores.featchList(query);
data && setData(data);
}catch(err){
throw err;
}
}
featchList(query); // 咱们把 query 当作参数传进去,把data和query 联动起来这样就能够达到搜索的功能啦。
}, [query]); // 随着 query 的变化,从新 mount,获取新的搜索的数据
return (
....
);
}
export default App;
复制代码
这里可能有同窗会问了,咱们为何要把 featchList
定义到 useEffect()
内部?直接和之前的写法同样放在外面有什么区别吗?json
咱们来看这句话 ==若是你指定了一个 依赖列表 做为 useEffect、useMemo、useCallback 或 useImperativeHandle 的最后一个参数,它必须包含参与那次 React 数据流的全部值。这就包含了 props、state,以及任何由它们衍生而来的东西。==segmentfault
function ProductPage({ productId }) {
const [product, setProduct] = useState(null);
async function fetchProduct() {
const response = await fetch('http://myapi/product' + productId); // 使用了 productId prop
const json = await response.json();
setProduct(json);
}
useEffect(() => {
fetchProduct();
}, []); // 🔴 这样是无效的,由于 `fetchProduct` 使用了 `productId`
// ...
}
复制代码
function ProductPage({ productId }) {
const [product, setProduct] = useState(null);
useEffect(() => {
// 把这个函数移动到 effect 内部后,咱们能够清楚地看到它用到的值。
async function fetchProduct() {
const response = await fetch('http://myapi/product' + productId);
const json = await response.json();
setProduct(json);
}
fetchProduct();
}, [productId]); // ✅ 有效,由于咱们的 effect 只用到了 productId
// ...
}
复制代码
总结,若是使用了props,state,或者他们的衍生值,咱们须要把相关使用的函数放进
useEffect
中,而后把相关值放进useEffect
的第二个参数中api