首页 > 解决方案 > 如何在 ReactJS 中使用无状态组件进行 http 调用 onclick?

问题描述

我有一个 React 无状态函数组件 (SFC)。我希望用户单击一个按钮,然后从 SFC 发出一个 http 调用,当收到响应时,我想打开一个模式。使用 SFC 可以实现吗?还是我需要保留一个有状态的组件?

这是我的代码,它在加载时进行 http 调用,然后 onClick 打开模式。但我希望这两件事都在 onClick 事件中按顺序发生。

//HTTP CALL FUNCTION
function httpListCall(url) {
    const [list, setData] = React.useState(null);
    const [error, setError] = React.useState(null);
    React.useEffect(() => {
        axios
            .get(url)
            .then(function (response) {
                setData(response.data.ResultList);
            })
            .catch(function (error) {
                setError(error);
            })
    }, []);
    return { list, error };
};

//SFC
const ListContainer = () => {
    const { list, error } = httpListCall("/list.json"); //THIS IS ON LOAD NOW - I WANT TO CALL IT onClick
    const [modalShow, setModalShow] = React.useState(false);

    return(
        <React.Fragment>
            <div>
               <button onClick={() => setModalShow(true)}/> //WANT TO MAKE API CALL HERE AND THEN OPEN THE MODAL
            </div>
            <ModalWidget show={modalShow} list={advisorList} error={error} onHide={() => setModalShow(false)}/>
        </React.Fragment>
    )
}

export default ListContainer;
ReactDOM.render(<ListContainer/>, document.getElementById("app"));

我试图从一个函数进行 http 调用,但它给了我一个错误:“无效的钩子调用。只能在函数组件的主体内部调用钩子。”

标签: reactjs

解决方案


解决方案(更新):

您必须遵循自定义挂钩实现要求,正如我在您的问题下的评论中提到的那样 - 必须在您的自定义挂钩函数名称前使用名称“use”并更新 useEffect 依赖项。

function useHttpListCall(url) {
  const [list, setData] = React.useState(null);
  const [error, setError] = React.useState(null);
  React.useEffect(() => {
    axios
      .get(url)
      .then(function(response) {
        setData(response.data);
      })
      .catch(function(error) {
        setError(error);
      });
  }, [url]);
  return { list, error };
}

并像这样更新您的功能组件以使用您的自定义 Hook。

const ListContainer = () => {
  const [modalShow, setModalShow] = React.useState(false);
  const [endpoint, setEndpoint] = React.useState(null);

  const { list } = useHttpListCall(endpoint);

  const handleClick = () => {
    setModalShow(true);
    setEndpoint("https://api.github.com/users?since=135");
  };

  return (
    <React.Fragment>
      <div>
        <button onClick={handleClick}>Show modal of Github users</button>
      </div>
      {modalShow && list && (
        <div>
          {list.map(user => {
            return <div key={user.id}>{user.login}</div>;
          })}
        </div>
      )}
    </React.Fragment>
  );
};

我没有实现模态,因为您没有提供此组件的代码。

此处提供了完整的工作代码(供您用作参考):https ://codesandbox.io/s/simple-custom-hook-n6ysw


推荐阅读