【问题标题】:how do I perform conditial query params in axios?如何在 axios 中执行条件查询参数?
【发布时间】:2021-03-09 21:19:17
【问题描述】:

我正在尝试构建一个条件动态反应组件,在该组件中基于用户交互进行 API 调用,但如果用户在搜索栏中键入内容。我想添加search= 参数,否则使用/list 没有查询参数的端点。我目前正在使用 Axios ,我想知道一些方法来执行以下操作

const FeedsList = () => {
    const [feed, setFeed] = useState([]);
    const [currentPageUrl, setCurrentPageUrl] = useState("http://localhost:8001/api/v1/feeds/list/")
  

    const performSearch = () =>  {
      //setLoading(true)
      api.get(currentPageUrl).then(res => { // axios call 
        setLoading(false)
        setFeed(res.data.results)
      }).catch(function(error){
        console.log(error);
      });
    }
  
    const handleSearch = (e) =>{
      console.log(e.target.value)
      //performSearch();
    }

    useEffect(() => {
        performSearch()
      }, [currentPageUrl]);
    
      if (loading) return "Loading..."
    }


export const api = axios.create(
    {baseURL : 'http://localhost:8001/api/v1/feeds/list/'}
    )

用户输入

  <input type="text" placeholder="Enter  keyword" onChange={event => handleSearch(event)}/>

【问题讨论】:

  • 处理用户输入的其余代码在哪里?
  • @Nick 更新了,我忘记了用户输入
  • input 元素是由父元素渲染的吗?如果是这样,那么这需要在那里处理

标签: reactjs rest endpoint


【解决方案1】:

将用户输入存储到状态,而不是 URL,然后从初始值(列表)和用户输入(如果有)构造您的 URL:

const FeedsList = () => {
  const [loading, setLoading] = useState(false);
  const [feed, setFeed] = useState([]);
  const [searchString, setSearchString] = useState("");

  const performSearch = (searchString) => {
    setLoading(true);
    let url = "http://localhost:8001/api/v1/feeds/list/";
    // you might want to escape this value, and sanitize input on the server
    if (searchString) url = `${url}?search=${searchString}`;
    const cancelTokenSource = axios.CancelToken.source();
    return api
      .get(url, { cancelToken: cancelTokenSource.token })
      .then((res) => {
        setLoading(false);
        setFeed(res.data.results);
      })
      .catch(function (error) {
        console.log(error);
      });
    return cancelTokenSource;
  };

  const handleSearch = (event) => {
    setSearchString(event.target.value);
  };

  useEffect(() => {
    let token = performSearch(searchString);
    return () => token.cancel();
  }, [searchString]);

  if (loading) return "Loading...";
};

你可能想要去抖动或限制请求,这样你就不会在每次击键时用请求轰炸你的服务器

【讨论】:

  • 什么是setState 内置函数?
  • 我已经编辑了代码。应该是setSearchString
  • 并在performSearchuseEffect内的调用中添加了缺少的参数
  • 确定。你的意思是debounce or throttle requests 限制为每分钟 100 次还是去抖动方法
  • 现在每次(或几乎每次)击键都会触发新请求。它不是很好,并且会使 UI 不响应。使用 debounce,您的函数将在用户停止输入后稍有延迟后运行。使用 throttlle 请求将在特定时间内触发不超过一次。在这里您可以阅读有关此技术的更多信息:css-tricks.com/debouncing-throttling-explained-examples
【解决方案2】:

Axios api 允许将第二个参数传递给 get 方法,这是发送请求的配置。该config 对象采用params 属性,该属性将被解析并作为查询字符串附加到url。好消息是如果 params 对象是空的,那就像根本没有传递任何东西一样。在他们的 GitHub 页面上有一个更完整的示例 here

就请求的内容而言,传递一个空的 params 对象与不传递任何 params 对象是一样的。

// both lines request url looks like this => https://jsonplaceholder.typicode.com/users

axios.get('https://jsonplaceholder.typicode.com/users')
axios.get('https://jsonplaceholder.typicode.com/users', { params: {} })

要回答您的问题,您可以有条件地根据搜索输入中是否存在值来创建参数,如下所示:


    const performSearch = () =>  {
        const config = search === '' ? { 
            params: {} 
        } : { 
            params: { search } // same as { search: search }
        }
        
        api.get(currentPageUrl, config).then(res => { 
            // do something with response
        }).catch(function(error){
            console.log(error);
        });
    }

上面的假设是您将 search 值存储在某处的 state 中并将其添加到您的 useEffect 依赖项列表中,并在 performSearch 中引用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2021-08-30
    相关资源
    最近更新 更多