简体   繁体   English

在选择时将下拉值从 function 传递给 React.useEffect()

[英]Pass dropdown value from function to React.useEffect() on selection

Goal: I am trying to change the link inside the fetch() function with the value that comes from the dropdown.目标:我正在尝试使用来自下拉列表的值更改 fetch() function 内的链接。

Attempts:尝试:

1) I attempted passing the value to the function like GetAPILinks(Link_from_dropdown) and calling it in the onSelect function however I am getting an error stating: Invalid hook call. Hooks can only be called inside of the body of a function component 1) 我尝试将值传递给 function,如GetAPILinks(Link_from_dropdown)并在 onSelect function 中调用它,但是我收到一条错误消息: Invalid hook call. Hooks can only be called inside of the body of a function component Invalid hook call. Hooks can only be called inside of the body of a function component

2) I have also tried other methods of passing it by storing it in a variable inside GetAPILinks but resulted in errors. 2)我还尝试了通过将其存储在 GetAPILinks 内的变量中来传递它的其他方法,但导致错误。

I am starting to believe I am approaching this all wrong.我开始相信我正在接近这一切都是错误的。 Any advice or help would be great!任何建议或帮助都会很棒!

My Code:我的代码:

This code will fetch the data from a hard coded link and renders a dropdown button that prints the selected values to the console.

import React from 'react';
import { DropdownButton, Dropdown} from 'react-bootstrap';

const GetAPILinks = () => {
  const [apiData, setApiData] = React.useState([]);
  React.useEffect(() => {
    fetch('https://Random_API/Link_From_Dropdown_Goes_Here')
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        setApiData(data);
      });
  }, []);

  return (
    <DropdownButton id="dropdown-item-button" title="API Links" onSelect={function(evt){console.log(evt)}}>
        <Dropdown.Item as="button" eventKey='API_Link1'>Link 1</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link2'>Link 2</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link3'>Link 3</Dropdown.Item>
    </DropdownButton>          
  );
}

export default GetAPILinks;

You're pretty close here.你离这里很近。 You should track another state value for the fetch Url.您应该跟踪另一个 state 值以获取 Url。 Tracking it in a local variable, or calling the function directly won't trigger your component to render when the values change.在局部变量中跟踪它,或直接调用 function 不会触发您的组件在值更改时呈现。

const [fetchUrl, setFetchUrl] = useState(initialValue);

in your onSelect drop down you can set the value of the fetchUrl using the setFetchUrl function that the useState hook provides.onSelect下拉列表中,您可以使用setFetchUrl挂钩提供的fetchUrl function 设置useState的值。

Now all that is left is to tell your useEffect hook that it needs to execute whenever the fetchUrl state value changes.现在剩下的就是告诉您的useEffect挂钩,只要fetchUrl state 值更改,它就需要执行。 You should add fetchUrl to the deps array.您应该将fetchUrl添加到 deps 数组中。

It might look something like this:它可能看起来像这样:

const GetAPILinks = () => {
  const [apiData, setApiData] = React.useState([]);
  const [fetchUrl, setFetchUrl] = React.useState('');
  React.useEffect(() => {
    if (fetchUrl) {
      fetch(fetchUrl)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          setApiData(data);
        });
    }
  }, [fetchUrl]);

  return (
    <DropdownButton id="dropdown-item-button" title="API Links" onSelect={(e)=>{setFetchUrl(e.target.eventKey)}}>
        <Dropdown.Item as="button" eventKey='API_Link1'>Link 1</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link2'>Link 2</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link3'>Link 3</Dropdown.Item>
    </DropdownButton>          
  );
}

const GetAPILinks = () => {

const [apiData, setApiData] = React.useState([]);
const [url, setUrl] = React.useState(null);
React.useEffect(() => {
 if (url) {
  fetch('https://${url}`)
  .then((response) => {
    return response.json();
  })
  .then((data) => {
    setApiData(data);
  }});
}, [url]);

return (
<DropdownButton id="dropdown-item-button" title="API Links" 
    onSelect={evt=>setUrl(evt.key)}>
    <Dropdown.Item as="button" eventKey='API_Link1'>Link 
        1
    </Dropdown.Item>
  </DropdownButton>          
 );
}

 export default GetAPILinks;

You should create another state for current link and add it to useEffect dependencies.您应该为当前链接创建另一个 state 并将其添加到useEffect依赖项。

It should be something like that, I didn't test.应该是这样的,我没有测试。

import React from 'react';
import { DropdownButton, Dropdown} from 'react-bootstrap';

const GetAPILinks = () => {
  const [apiData, setApiData] = React.useState([]);
  const [currentLink, setCurrentLink] = React.useState('');

  React.useEffect(() => {
    fetch(`https://Random_API/${currentLink}`)
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        setApiData(data);
      });
  }, [currentLink]);

  return (
    <DropdownButton id="dropdown-item-button" title="API Links" onSelect={(e)=>{setCurrentLink(e.target.eventKey)}}>
        <Dropdown.Item as="button" eventKey='API_Link1'>Link 1</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link2'>Link 2</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link3'>Link 3</Dropdown.Item>
    </DropdownButton>          
  );
}

export default GetAPILinks;

Hope it helps.希望能帮助到你。

Add another piece of state to track the selected dropdown value再添加一块 state 来跟踪选中的下拉值

const [query, setQuery] = useState();

And add query to the dependency array of the effect and only make the fetch request when query is truthy并将query添加到效果的依赖数组中,并且仅在query为真时才发出获取请求

React.useEffect(() => {
  query && fetch(`https://Random_API/${query}`)
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      setApiData(data);
    });
}, [query]);

编辑 mystifying-nash-wtfrc

A cleaner solution may be to factor out the fetch logic to its own function, call that with the callback, and store only the result in state一个更干净的解决方案可能是将获取逻辑分解为它自己的 function,用回调调用它,并将结果仅存储在 state

const GetAPILinks = () => {
  const [apiData, setApiData] = useState([]);

  const fetchData = query => fetch(`https://Random_API/${query}`)
    .then((response) => {
      return response.json();
    })
    .then(setApiData(data));

  return (
    <DropdownButton id="dropdown-item-button" title="API Links" onSelect={fetchData}>
        <Dropdown.Item as="button" eventKey='API_Link1'>Link 1</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link2'>Link 2</Dropdown.Item>
        <Dropdown.Item as="button" eventKey='API_Link3'>Link 3</Dropdown.Item>
    </DropdownButton>          
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM