我创建了一个自定义钩子来获取数据并尝试实现它,但无济于事。
这是我的自定义钩子:
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”)时,我确实看到它出现在控制台中。但是没有网络请求或其他任何请求。我在做什么错了?
答案 0 :(得分:0)
我在Codepen中创建了自定义钩子的副本,删除了useReducer部分,使用了不同的HTTP请求,并发现我能够成功进行网络调用。
也许问题出在您的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));
还,您是否尝试过在控制台中添加控制台日志以查看是否存在任何错误?