自定义钩子不触发点击

时间:2020-09-11 14:46:02

标签: javascript reactjs axios react-hooks

我创建了一个自定义钩子来获取数据并尝试实现它,但无济于事。

这是我的自定义钩子:

import { useReducer } from "react";
import axios from "axios";

const dataFetchReducer = (state, action) => {
  switch (action.type) {
    case "FETCH_INIT":
      return {
        ...state,
        isLoading: true,
        isError: false,
      };
    case "FETCH_SUCCESS":
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: action.payload,
      };
    case "FETCH_FAILURE":
      return {
        ...state,
        isLoading: false,
        isError: true,
      };
    default:
      throw new Error();
  }
};

const useApi = (method) => {
  const [state, dispatch] = useReducer(dataFetchReducer, {
    isLoading: false,
    isError: false,
    data: null,
  });

  axios.defaults.baseURL = "https://code-portfolio-f44c5.firebaseio.com";

  const fetchData = async (url, data) => {
    dispatch({ type: "FETCH_INIT" });

    try {
      const result = await axios[method](url, JSON.parse(data));

      dispatch({ type: "FETCH_SUCCESS", payload: result.data });
    } catch (error) {
      dispatch({ type: "FETCH_FAILURE" });
    }
  };

  return [state, fetchData];
};

export default useApi;

这是我希望在onClick触发的模式:

const [{ data, isLoading, isError }, doFetch] = useApi("post");

function createSnippet(e) {
  doFetch(`/snippets/${framework}.json`, {
    description: description,
    category: category,
    title: title,
    snippet: snippet,
  });
  e.preventDefault();
}

return (
  <Modal
    isOpen={modalIsOpen}
    shouldCloseOnOverlayClick={true}
    onRequestClose={() => setIsOpen(false)}
    style={modalStyles}
    onAfterClose={resetStateVariables}
  >
    <ModalContainer>
      <HeaderContainer>
        <Header>Add a snippet</Header>
      </HeaderContainer>
      <BodyContainer>
        <Form>
          <InputContainer>
            <LabelledSelect
              label="Select framework"
              options={frameworkOptions}
              onChange={(e) => setFramework(e.target.value)}
              value={framework}
            />
          </InputContainer>
          <InputContainer>
            <LabelledSelect
              label="Select category"
              options={categoryOptions}
              onChange={(e) => setCategory(e.target.value)}
              value={category}
            />
          </InputContainer>
          <InputContainer>
            <LabelledTextInput
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              label="Title"
              placeholder="What's the title of this snippet?"
            />
          </InputContainer>
          <InputContainer>
            <LabelledTextarea
              label="Describe your snippet"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="What does your snippet do?"
            />
          </InputContainer>
          <InputContainer>
            <AceEditor
              mode="javascript"
              theme="twilight"
              onChange={setSnippet}
              editorProps={{ $blockScrolling: true }}
              setOptions={{
                enableBasicAutocompletion: true,
                enableLiveAutocompletion: true,
                enableSnippets: true,
              }}
              width="100%"
              height="200px"
              value={snippet}
            />
          </InputContainer>
          <Button onClick={createSnippet}>Create snippet</Button>
        </Form>
      </BodyContainer>
    </ModalContainer>
  </Modal>
);

所以发生的事情实际上什么也没有。当我尝试检查隐藏的内容并在try块中插入console.log(“ check”)时,我确实看到它出现在控制台中。但是没有网络请求或其他任何请求。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

我在Codepen中创建了自定义钩子的副本,删除了useReducer部分,使用了不同的HTTP请求,并发现我能够成功进行网络调用。

API documentation

也许问题出在您的API URL。

所有这些值(特别是framework)有效吗?

function createSnippet(e) {
    doFetch(`/snippets/${framework}.json`, {
      description: description,
      category: category,
      title: title,
      snippet: snippet,
    });
    e.preventDefault();
  }

  return [mockState, fetchData];
};

应该是JSON.stringify吗?还是需要转换?根据{{​​3}},它们将按原样传递JS数据对象。

const result = await axios[method](url, JSON.parse(data));

还,您是否尝试过在控制台中添加控制台日志以查看是否存在任何错误?