最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫(xiě)

 更新時(shí)間:2023年03月09日 15:10:01   作者:馮心心愛(ài)吃肉  
這篇文章主要為大家介紹了學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫(xiě)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

最近業(yè)務(wù)沒(méi)有之前緊張了,也是消失了一段時(shí)間,也總結(jié)了一些之前業(yè)務(wù)上的問(wèn)題。

和同事溝通也是發(fā)現(xiàn)普通的async + await + 封裝api在復(fù)雜業(yè)務(wù)場(chǎng)景下針對(duì)于請(qǐng)求的業(yè)務(wù)邏輯比較多,也是推薦我去學(xué)習(xí)一波ahooks,由于問(wèn)題起源于請(qǐng)求,因此作者也是直接從 useRequest 開(kāi)始看起。

ahooks useRequest鏈接:

ahooks-v2.js.org/zh-CN/hooks…

實(shí)現(xiàn)

話(huà)不多說(shuō),手寫(xiě)直接開(kāi)始,參考幾個(gè)比較常用的 useRequest 能力來(lái)一個(gè)個(gè)實(shí)現(xiàn)吧。

基礎(chǔ)版(雛形)

先上代碼:

useRequest.ts

interface UseRequestOptionsProps {
  /*
   * 請(qǐng)求參數(shù)
   */
  initialData?: object;
  /*
   * 請(qǐng)求成功回調(diào)
   */
  onSuccess?: (res: any) => void;
}
const useRequest = (
  requestFn: (
    initialData?: object | string | [],
  ) => Promise<SetStateAction<any>>,
  options: UseRequestOptionsProps,
) => {
  const [data, setData] = useState<SetStateAction<any>>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const { initialData, onSuccess } = options;
  useEffect(() => {
    setLoading(true);
    setError(null);
    setData(null);
    request();
  }, [requestFn]);
  // useRequest業(yè)務(wù)邏輯
  const request = async () => {
    try {
      const res = await requestFn(initialData);
      setData(res);
      // 請(qǐng)求成功響應(yīng)回調(diào)
      onSuccess && onSuccess(res);
    } catch (err) {
      err && setError(JSON.stringify(err));
    } finally {
      setLoading(false);
    }
  };
  return { data, loading, error };
};
export default useRequest;

使用

const { data, loading, error } = useRequest(
    queryCompensatoryOrderSituation,
    {
        initialData: {
            compensatoryId,
        }
        onSuccess: (res) => {
            console.log('success request!', res);
        },
    },
);

useRequest 對(duì)于請(qǐng)求函數(shù)的寫(xiě)法并無(wú)過(guò)多要求,只要是一個(gè)異步function且返回一個(gè)promise對(duì)象,即可傳入useRequest的第一個(gè)參數(shù)中,而第二個(gè)參數(shù)則是一系列的可選配置項(xiàng),雛形版本我們暫時(shí)只支持onSuccess

手動(dòng)觸發(fā)

代碼改造后:

useRequest.ts

interface UseRequestOptionsProps {
  /*
   * 手動(dòng)開(kāi)啟
   */
  manual?: boolean;
  /*
   * 請(qǐng)求參數(shù)
   */
  initialData?: object;
  /*
   * 請(qǐng)求成功回調(diào)
   */
  onSuccess?: (res: any) => void;
}
const useRequest = (
  requestFn: (
    initialData?: object | string | [],
  ) => Promise<SetStateAction<any>>,
  options: UseRequestOptionsProps,
) => {
  const [data, setData] = useState<SetStateAction<any>>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const { manual, initialData, onSuccess } = options;
  useEffect(() => {
    setLoading(true);
    setError(null);
    setData(null);
    !manual && request();
  }, [manual]);
  // useRequest業(yè)務(wù)邏輯
  const request = async () => {
    try {
      const res = await requestFn(initialData);
      setData(res);
      // 請(qǐng)求成功響應(yīng)回調(diào)
      onSuccess && onSuccess(res);
    } catch (err) {
      err && setError(JSON.stringify(err));
    } finally {
      setLoading(false);
    }
  };
  return { data, loading, error, request };
};
export default useRequest;

使用

const { data, loading, error, request } = useRequest(
    queryCompensatoryOrderSituation,
    {
        manual: true,
        initialData: {
            compensatoryId,
        },
        onSuccess: (res) => {
            console.log('success request!', res);
        },
    },
);
request();

手動(dòng)執(zhí)行的邏輯主要是根據(jù)manual參數(shù)砍掉useRequest mount階段的渲染請(qǐng)求,把執(zhí)行請(qǐng)求的能力暴露出去,在頁(yè)面中去手動(dòng)調(diào)用request()來(lái)觸發(fā)。

輪詢(xún)與手動(dòng)取消

代碼改造后:

useRequest.ts

interface UseRequestOptionsProps {
  /*
   * 手動(dòng)開(kāi)啟
   */
  manual?: boolean;
  /*
   * 請(qǐng)求參數(shù)
   */
  initialData?: object;
  /*
   * 輪詢(xún)
   */
  pollingInterval?: number | null;
  /*
   * 請(qǐng)求成功回調(diào)
   */
  onSuccess?: (res: any) => void;
}
const useRequest = (
  requestFn: (
    initialData?: object | string | [],
  ) => Promise<SetStateAction<any>>,
  options: UseRequestOptionsProps,
) => {
  const [data, setData] = useState<SetStateAction<any>>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const status = useRef<boolean>(false);
  const pollingIntervalTimer = useRef<NodeJS.Timer | null>(null);
  const { manual, initialData, pollingInterval, onSuccess } = options;
  useEffect(() => {
    setLoading(true);
    setError(null);
    setData(null);
    !manual && request();
  }, [manual]);
  // useRequest業(yè)務(wù)邏輯
  const request = async () => {
   try {
      !status.current && (status.current = true);
      if (pollingInterval && status.current) {
        pollingIntervalTimer.current = setTimeout(() => {
          status.current && request();
        }, pollingInterval);
      }
      const res = await requestFn(initialData);
      setData(res);
      // 請(qǐng)求成功響應(yīng)回調(diào)
      onSuccess && onSuccess(res);
    } catch (err) {
      err && setError(JSON.stringify(err));
    } finally {
      setLoading(false);
    }
  };
  return { data, loading, error, request, cancel };
};
// 取消
const cancel = () => {
  if (pollingIntervalTimer.current) {
    clearTimeout(pollingIntervalTimer.current);
    pollingIntervalTimer.current = null;
    status.current && (status.current = false);
  }
};
export default useRequest;

使用

const { data, loading, error, request, cancel } = useRequest(
    queryCompensatoryOrderSituation,
    {
        manual: true,
        initialData: {
            compensatoryId,
        },
        pollingInterval: 1000,
        onSuccess: (res) => {
            console.log('success request!', res);
        },
    },
);
request();
...
// 輪詢(xún)到理想數(shù)據(jù)后
cancel();

輪詢(xún)的支持在hook中主要用到了timer setTimeout的遞歸思路,同時(shí)給出一個(gè)status狀態(tài)值判斷是否在輪詢(xún)中,當(dāng)調(diào)用端執(zhí)行cancel(),status則為false;當(dāng)輪詢(xún)開(kāi)始,則statustrue。

cancel()的能力 主要也是取消了timer的遞歸請(qǐng)求邏輯,并且輪詢(xún)的業(yè)務(wù)場(chǎng)景和manual: true配合很多。

依賴(lài)請(qǐng)求(串型請(qǐng)求)

代碼改造后:

useRequest.ts

interface UseRequestOptionsProps {
  /*
   * 手動(dòng)開(kāi)啟
   */
  manual?: boolean;
  /*
   * 請(qǐng)求參數(shù)
   */
  initialData?: object;
  /*
   * 輪詢(xún)
   */
  pollingInterval?: number | null;
  /*
   * 準(zhǔn)備,用于依賴(lài)請(qǐng)求
   */
  ready?: boolean;
  /*
   * 請(qǐng)求成功回調(diào)
   */
  onSuccess?: (res: any) => void;
}
const useRequest = (
  requestFn: (
    initialData?: object | string | [],
  ) => Promise<SetStateAction<any>>,
  options: UseRequestOptionsProps,
) => {
  const [data, setData] = useState<SetStateAction<any>>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const status = useRef<boolean>(false);
  const pollingIntervalTimer = useRef<NodeJS.Timer | null>(null);
  const {
    manual,
    initialData,
    pollingInterval,
    ready = true,
    onSuccess,
  } = options;
  useEffect(() => {
    setLoading(true);
    setError(null);
    setData(null);
    !manual && ready && request();
  }, [manual, ready]);
  // useRequest業(yè)務(wù)邏輯
  const request = async () => {
   try {
      !status.current && (status.current = true);
      if (pollingInterval && status.current) {
        pollingIntervalTimer.current = setTimeout(() => {
          status.current && request();
        }, pollingInterval);
      }
      const res = await requestFn(initialData);
      setData(res);
      // 請(qǐng)求成功響應(yīng)回調(diào)
      onSuccess && onSuccess(res);
    } catch (err) {
      err && setError(JSON.stringify(err));
    } finally {
      setLoading(false);
    }
  };
  return { data, loading, error, request, cancel };
};
// 取消
const cancel = () => {
  if (pollingIntervalTimer.current) {
    clearTimeout(pollingIntervalTimer.current);
    pollingIntervalTimer.current = null;
    status.current && (status.current = false);
  }
};
export default useRequest;

使用

const [mountLoading, setMountLoading] = useState<boolean>(false);
useEffect(() => {
    setMountLoading(true);
}, [2000])
const { data, loading, error, request, cancel } = useRequest(
    queryCompensatoryOrderSituation,
    {
        initialData: {
            compensatoryId,
        },
        pollingInterval: 1000,
        ready: mountLoading,
        onSuccess: (res) => {
            console.log('success request!', res);
        },
    },
);

依賴(lài)請(qǐng)求的思路就是在hook中加入一個(gè)ready字段,也是在基于manual一層的限制后又加了一層,來(lái)判斷是否在hook加載時(shí)是否做默認(rèn)請(qǐng)求,而當(dāng)option中的ready更新(為true)時(shí),hook自動(dòng)更新從而發(fā)起請(qǐng)求。

常用于頁(yè)面中A請(qǐng)求完成后執(zhí)行B請(qǐng)求,B請(qǐng)求的ready字段依賴(lài)于A請(qǐng)求的data/loading字段。

防抖與節(jié)流

防抖和節(jié)流的實(shí)現(xiàn)比較簡(jiǎn)單,依賴(lài)于lodash庫(kù),包裝了一下request函數(shù)的請(qǐng)求內(nèi)容。

代碼如下:

useRequest.ts

interface UseRequestOptionsProps {
  /*
   * 手動(dòng)開(kāi)啟
   */
  manual?: boolean;
  /*
   * 請(qǐng)求參數(shù)
   */
  initialData?: object;
  /*
   * 輪詢(xún)
   */
  pollingInterval?: number | null;
  /*
   * 準(zhǔn)備,用于依賴(lài)請(qǐng)求
   */
  ready?: boolean;
  /*
   * 防抖
   */
  debounceInterval?: number;
  /*
   * 節(jié)流
   */
  throttleInterval?: number;
  /*
   * 請(qǐng)求成功回調(diào)
   */
  onSuccess?: (res: any) => void;
}
const useRequest = (
  requestFn: (
    initialData?: object | string | [],
  ) => Promise<SetStateAction<any>>,
  options: UseRequestOptionsProps,
) => {
  const [data, setData] = useState<SetStateAction<any>>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const status = useRef<boolean>(false);
  const pollingIntervalTimer = useRef<NodeJS.Timer | null>(null);
  const {
    manual,
    initialData,
    pollingInterval,
    ready = true,
    debounceInterval,
    throttleInterval
    onSuccess,
  } = options;
  useEffect(() => {
    setLoading(true);
    setError(null);
    setData(null);
    !manual && ready && request();
  }, [manual, ready]);
 //  請(qǐng)求
 const request = () => {
  if (debounceInterval) {
    lodash.debounce(requestDoing, debounceInterval)();
  } else if (throttleInterval) {
    lodash.throttle(requestDoing, throttleInterval)();
  } else {
    requestDoing();
  }
};
// useRequest業(yè)務(wù)邏輯
const requestDoing = async () => {
  try {
    !status.current && (status.current = true);
    if (pollingInterval && status.current) {
      pollingIntervalTimer.current = setTimeout(() => {
        status.current && request();
      }, pollingInterval);
    }
    const res = await requestFn(initialData);
    setData(res);
    // 請(qǐng)求成功響應(yīng)回調(diào)
    onSuccess && onSuccess(res);
  } catch (err) {
    err && setError(JSON.stringify(err));
  } finally {
    setLoading(false);
  }
};
// 取消
const cancel = () => {
  if (pollingIntervalTimer.current) {
    clearTimeout(pollingIntervalTimer.current);
    pollingIntervalTimer.current = null;
    status.current && (status.current = false);
  }
};
export default useRequest;

使用

const { data, loading, error, request, cancel } = useRequest(
    queryCompensatoryOrderSituation,
    {
        manual: true,
        initialData: {
            compensatoryId,
        },
        debounceInterval: 1000,     // 防抖
        throttleInterval: 1000,     // 節(jié)流
        onSuccess: (res) => {
            console.log('success request!', res);
        },
    },
);
for(let i = 0; i < 10000; i++) {
    request();
}

hook中,通過(guò)lodash.debounce/lodash.throttle來(lái)包裝request函數(shù)主體,通過(guò)option中的判斷來(lái)執(zhí)行對(duì)應(yīng)的包裝體函數(shù)。

緩存與依賴(lài)更新

改造后的代碼(最終代碼)如下:

useRequest.ts

import {
  useState,
  useEffect,
  useRef,
  SetStateAction,
  useCallback,
} from 'react';
import lodash from 'lodash';
interface UseRequestOptionsProps {
  /*
   * 手動(dòng)開(kāi)啟
   */
  manual?: boolean;
  /*
   * 請(qǐng)求參數(shù)
   */
  initialData?: object;
  /*
   * 輪詢(xún)
   */
  pollingInterval?: number | null;
  /*
   * 準(zhǔn)備,用于依賴(lài)請(qǐng)求
   */
  ready?: boolean;
  /*
   * 防抖
   */
  debounceInterval?: number;
  /*
   * 節(jié)流
   */
  throttleInterval?: number;
  /*
   * 延遲loading為true的時(shí)間
   */
  loadingDelay?: number;
  /*
   * 依賴(lài)
   */
  refreshDeps?: any[];
  /*
   * 請(qǐng)求成功回調(diào)
   */
  onSuccess?: (res: any) => void;
}
const useRequest = (
  requestFn: (
    initialData?: object | string | [],
  ) => Promise<SetStateAction<any>>,
  options: UseRequestOptionsProps,
) => {
  const [data, setData] = useState<SetStateAction<any>>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const status = useRef<boolean>(false);
  const pollingIntervalTimer = useRef<NodeJS.Timer | null>(null);
  const {
    manual,
    initialData,
    pollingInterval,
    ready = true,
    debounceInterval,
    throttleInterval,
    loadingDelay,
    refreshDeps,
    onSuccess,
  } = options;
  useEffect(() => {
    if (loadingDelay) {
      setTimeout(() => {
        status && setLoading(true);
      }, loadingDelay);
    }
    setError(null);
    setData(null);
    // 手動(dòng)觸發(fā)request
    !manual && ready && request();
  }, [manual, ready, ...(Array.isArray(refreshDeps) ? refreshDeps : [])]);
  //  請(qǐng)求
  const request = () => {
    if (debounceInterval) {
      lodash.debounce(requestDoing, debounceInterval)();
    } else if (throttleInterval) {
      lodash.throttle(requestDoing, throttleInterval)();
    } else {
      requestDoing();
    }
  };
  // useRequest業(yè)務(wù)邏輯
  const requestDoing = async () => {
    try {
      !status.current && (status.current = true);
      if (pollingInterval && status.current) {
        pollingIntervalTimer.current = setTimeout(() => {
          status.current && request();
        }, pollingInterval);
      }
      const res = await requestFn(initialData);
      setData(res);
      // 請(qǐng)求成功響應(yīng)回調(diào)
      onSuccess && onSuccess(res);
    } catch (err) {
      err && setError(JSON.stringify(err));
    } finally {
      setLoading(false);
    }
  };
  // 取消
  const cancel = () => {
    if (pollingIntervalTimer.current) {
      clearTimeout(pollingIntervalTimer.current);
      pollingIntervalTimer.current = null;
      status.current && (status.current = false);
    }
  };
  // 緩存
  const cachedFetchData = useCallback(() => data, [data]);
  return { data, loading, error, request, cancel, cachedFetchData };
};
export default useRequest;

使用

const [mountLoading, setMountLoading] = useState<boolean>(false);
const [updateLoading, setUpdateLoading] = useState<boolean>(false);
setTimeout(() => {
    setMountLoading(true);
}, 1000);
setTimeout(() => {
    setUpdateLoading(true);
}, 2000);
const { data, loading, error, request, cancel, cachedFetchData } = useRequest(
    queryCompensatoryOrderSituation,
    {
        manual: true,
        initialData: {
            compensatoryId,
        },
        debounceInterval: 1000,     // 防抖
        throttleInterval: 1000,     // 節(jié)流
        refreshDeps: [mountLoading, updateLoading],
        onSuccess: (res) => {
            console.log('success request!', res);
        },
    },
);

緩存的主體思路是在useRequest中拿到第一次數(shù)據(jù)后通過(guò)useCallback來(lái)透出data依賴(lài)來(lái)保存,同時(shí)向外暴露一個(gè)cachedFetchData來(lái)過(guò)渡datanull到請(qǐng)求到接口數(shù)據(jù)的過(guò)程。

依賴(lài)更新的思路則是在頁(yè)面中給useRequest一系列依賴(lài)狀態(tài)一并加入在hook的請(qǐng)求副作用中,監(jiān)聽(tīng)到頁(yè)面中依賴(lài)改變,則重新請(qǐng)求,具體實(shí)現(xiàn)則是refreshDeps參數(shù)。

結(jié)尾

花了一上午時(shí)間,一個(gè)簡(jiǎn)易版本的useRequest實(shí)現(xiàn)了,也是通過(guò)實(shí)現(xiàn)學(xué)習(xí)到了一些請(qǐng)求思路,在業(yè)務(wù)復(fù)雜的場(chǎng)景下也是很需要這類(lèi)請(qǐng)求工具來(lái)讓開(kāi)發(fā)者的注意力從請(qǐng)求處理轉(zhuǎn)移集中在業(yè)務(wù)邏輯中。

以上就是學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫(xiě)的詳細(xì)內(nèi)容,更多關(guān)于ahooks useRequest手寫(xiě)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react函數(shù)組件useState異步,數(shù)據(jù)不能及時(shí)獲取到的問(wèn)題

    react函數(shù)組件useState異步,數(shù)據(jù)不能及時(shí)獲取到的問(wèn)題

    這篇文章主要介紹了react函數(shù)組件useState異步,數(shù)據(jù)不能及時(shí)獲取到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React淺析Fragments使用方法

    React淺析Fragments使用方法

    這篇文章主要介紹了React Fragments使用方法,關(guān)于react Fragments,React中一個(gè)常見(jiàn)模式是為一個(gè)組件返回多個(gè)元素。Fragments 可以讓你聚合一個(gè)子元素列表,并且不在DOM中增加額外節(jié)點(diǎn)
    2022-12-12
  • React+Node.js實(shí)現(xiàn)大文件傳輸與斷點(diǎn)續(xù)傳

    React+Node.js實(shí)現(xiàn)大文件傳輸與斷點(diǎn)續(xù)傳

    這篇文章主要為大家詳細(xì)介紹了如何使用React前端和Node.js后端實(shí)現(xiàn)大文件傳輸和斷點(diǎn)續(xù)傳的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考下
    2024-12-12
  • React Router6.x路由表封裝的兩種寫(xiě)法

    React Router6.x路由表封裝的兩種寫(xiě)法

    本文主要介紹了React Router6.x路由表封裝的兩種寫(xiě)法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Ant?Design?組件庫(kù)之步驟條實(shí)現(xiàn)

    Ant?Design?組件庫(kù)之步驟條實(shí)現(xiàn)

    這篇文章主要為大家介紹了Ant?Design組件庫(kù)之步驟條實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 使用React和Redux Toolkit實(shí)現(xiàn)用戶(hù)登錄功能

    使用React和Redux Toolkit實(shí)現(xiàn)用戶(hù)登錄功能

    在React中,用戶(hù)登錄功能是一個(gè)常見(jiàn)的需求,為了實(shí)現(xiàn)該功能,需要對(duì)用戶(hù)輸入的用戶(hù)名和密碼進(jìn)行驗(yàn)證,并將驗(yàn)證結(jié)果保存到應(yīng)用程序狀態(tài)中,在React中,可以使用Redux Toolkit來(lái)管理應(yīng)用程序狀態(tài),從而實(shí)現(xiàn)用戶(hù)登錄功能,需要詳細(xì)了解可以參考下文
    2023-05-05
  • 一文帶你搞懂useCallback的使用方法

    一文帶你搞懂useCallback的使用方法

    useCallback是用來(lái)幫忙緩存函數(shù)的,當(dāng)依賴(lài)項(xiàng)沒(méi)有發(fā)生變化時(shí),返回緩存的指針,而props涉及到復(fù)雜對(duì)象類(lèi)型都是通過(guò)指針來(lái)傳遞到,下面這篇文章主要給大家介紹了關(guān)于useCallback使用的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • React useEffect使用教程

    React useEffect使用教程

    useEffect是react v16.8新引入的特性。我們可以把useEffect hook看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三個(gè)函數(shù)的組合
    2022-10-10
  • React Hooks獲取數(shù)據(jù)實(shí)現(xiàn)方法介紹

    React Hooks獲取數(shù)據(jù)實(shí)現(xiàn)方法介紹

    這篇文章主要介紹了react hooks獲取數(shù)據(jù),文中給大家介紹了useState dispatch函數(shù)如何與其使用的Function Component進(jìn)行綁定,實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • 基于React.js實(shí)現(xiàn)原生js拖拽效果引發(fā)的思考

    基于React.js實(shí)現(xiàn)原生js拖拽效果引發(fā)的思考

    這篇文章主要為大家詳細(xì)介紹了基于React.js實(shí)現(xiàn)原生js拖拽效果,繼而引發(fā)的一系列思考,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03

最新評(píng)論

盐津县| 丹东市| 闻喜县| 威信县| 天柱县| 陕西省| 石家庄市| 寿宁县| 融水| 江山市| 肇东市| 周口市| 永善县| 扶绥县| 鹰潭市| 射阳县| 三都| 湾仔区| 通化县| 仁寿县| 福建省| 乌拉特前旗| 加查县| 北流市| 夏河县| 双峰县| 莆田市| 古蔺县| 丹阳市| 南充市| 汾西县| 新野县| 怀安县| 磐安县| 景东| 确山县| 金沙县| 浦东新区| 曲松县| 合作市| 扎赉特旗|