pet*_*gan 11 javascript reactjs react-hooks
我刚刚开始使用React钩子,我想知道AJAX请求应该如何看待?
我尝试了很多尝试,但是无法让它工作,也不知道实现它的最佳方法.以下是我最近的尝试:
import React, { useState, useEffect } from 'react';
const App = () => {
const URL = 'http://api.com';
const [data, setData] = useState({});
useEffect(() => {
const resp = fetch(URL).then(res => {
console.log(res)
});
});
return (
<div>
// display content here
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
Pau*_*ald 26
您可以创建一个名为的自定义钩子useFetch来实现useEffect钩子.
通过将空数组作为第二个参数传递给useEffect钩子将触发请求componentDidMount.
见下面的代码.
import React, { useState, useEffect } from 'react';
const useFetch = (url) => {
const [data, updateData] = useState(undefined);
// empty array as second argument equivalent to componentDidMount
useEffect(() => {
async function fetchData() {
const response = await fetch(url);
const json = await response.json();
updateData(json);
}
fetchData();
}, [url]);
return data;
};
const App = () => {
const URL = 'http://www.example.json';
const result = useFetch(URL);
return (
<div>
{JSON.stringify(result)}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
效果很好...在这里,您可以:
编辑:根据版本更改进行更新(感谢@mgol在评论中引起我的注意...
import React, { useState, useEffect } from 'react';
const useFetch = url => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const fetchUser = async () => {
const response = await fetch(url);
const data = await response.json();
const [user] = data.results;
setData(user);
setLoading(false);
};
useEffect(() => {
fetchUser();
}, []);
return { data, loading };
};
const App = () => {
const { data, loading } = useFetch('https://api.randomuser.me/');
return (
<div className="App">
{loading ? (
<div>Loading...</div>
) : (
<React.Fragment>
<div className="name">
{data.name.first} {data.name.last}
</div>
<img className="cropper" src={data.picture.large} alt="avatar" />
</React.Fragment>
)}
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
现场演示:
到目前为止很棒的答案,但是我会在你想要触发请求的时候添加一个自定义钩子,因为你也可以这样做.
function useTriggerableEndpoint(fn) {
const [res, setRes] = useState({ data: null, error: null, loading: null });
const [req, setReq] = useState();
useEffect(
async () => {
if (!req) return;
try {
setRes({ data: null, error: null, loading: true });
const { data } = await axios(req);
setRes({ data, error: null, loading: false });
} catch (error) {
setRes({ data: null, error, loading: false });
}
},
[req]
);
return [res, (...args) => setReq(fn(...args))];
}
Run Code Online (Sandbox Code Playgroud)
你可以使用这个钩子为特定的API方法创建一个函数,如果你愿意的话,但是要注意这个抽象并不是严格要求的,并且可能非常危险(带有钩子的松散函数不是一个好主意,如果它在React组件函数的上下文之外使用).
const todosApi = "https://jsonplaceholder.typicode.com/todos";
function postTodoEndpoint() {
return useTriggerableEndpoint(data => ({
url: todosApi,
method: "POST",
data
}));
}
Run Code Online (Sandbox Code Playgroud)
最后,从您的功能组件中
const [newTodo, postNewTodo] = postTodoEndpoint();
function createTodo(title, body, userId) {
postNewTodo({
title,
body,
userId
});
}
Run Code Online (Sandbox Code Playgroud)
然后只指向createTodo一个onSubmit或onClick处理程序.newTodo将拥有您的数据,加载和错误状态.沙盒代码就在这里.
use-http是一个小小的反应 useFetch 钩子,使用如下:https ://use-http.com
import useFetch from 'use-http'
function Todos() {
const [todos, setTodos] = useState([])
const { request, response } = useFetch('https://example.com')
// componentDidMount
useEffect(() => { initializeTodos() }, [])
async function initializeTodos() {
const initialTodos = await request.get('/todos')
if (response.ok) setTodos(initialTodos)
}
async function addTodo() {
const newTodo = await request.post('/todos', {
title: 'no way',
})
if (response.ok) setTodos([...todos, newTodo])
}
return (
<>
<button onClick={addTodo}>Add Todo</button>
{request.error && 'Error!'}
{request.loading && 'Loading...'}
{todos.map(todo => (
<div key={todo.id}>{todo.title}</div>
)}
</>
)
}
Run Code Online (Sandbox Code Playgroud)
或者,如果你不想自己管理状态,你可以这样做
function Todos() {
// the dependency array at the end means `onMount` (GET by default)
const { loading, error, data } = useFetch('/todos', [])
return (
<>
{error && 'Error!'}
{loading && 'Loading...'}
{data && data.map(todo => (
<div key={todo.id}>{todo.title}</div>
)}
</>
)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7242 次 |
| 最近记录: |