#javascript #reactjs #wrapper
Вопрос:
У меня есть много функций, которые выглядят так
doSomething = async (...) => {
try {
this.setState({loading: true});
...
var result = await Backend.post(...);
...
this.setState({loading: false});
} catch(err) {
this.setState({error: err});
}
}
В основном у меня есть 2 переменные загрузки и ошибки, которыми я должен управлять для многих функций, и код в основном одинаков для всех из них. Поскольку в javascript нет декораторов, и я не хочу устанавливать для этого какую-либо экспериментальную библиотеку, как я мог бы обернуть эту функцию, чтобы удалить дублированные состояния набора сверху ?
Комментарии:
1. Почему бы просто не извлечь его в метод, чтобы вы сделали, например
doSomething = this.manageLoading(async () => { var result = await Backend.post(...); ... })
.
Ответ №1:
Вот мой текущий способ, я передаю функцию в качестве параметра.
У нас много API, бэкэнд для извлечения данных, мы должны обрабатывать ошибки и что-то делать с данными.
Различаются только данные службы, ошибка обработки одна и та же.
private processServiceResponse(resp: any, doSthWithData: (data: any) => void) {
let { errors } = resp;
if (this.hasError(errors)) {
this.handleServiceErr(errors);
return;
}
let data = resp;
if (resp amp;amp; resp.data) {
data = resp.data;
}
doSthWithData(data);
}
И вот как я передаю функцию в качестве параметра.
let rest1 = service1.getData();
processServiceResponse(rest1,(data)=>{
//only need to focus with processing data.
})
PS: Это кодировка машинописного текста.
Ответ №2:
если вы используете компоненты функций, вы можете определить пользовательский крюк, чтобы избежать повторения кода
//useFetch.js
import { useState, useEffect } from 'react';
import axios from 'axios';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
setLoading('loading...')
setData(null);
setError(null);
const source = axios.CancelToken.source();
axios.get(url, { cancelToken: source.token })
.then(res => {
setLoading(false);
//checking for multiple responses for more flexibility
//with the url we send in.
res.data.content amp;amp; setData(res.data.content);
res.content amp;amp; setData(res.content);
})
.catch(err => {
setLoading(false)
setError('An error occurred. Awkward..')
})
return () => {
source.cancel();
}
}, [url])
return { data, loading, error }
export default useFetch;
использование:
import useFetch from './useFetch';
import './App.css';
function App() {
const { data: quote, loading, error } =
useFetch('https://api.quotable.io/random')
return (
<div className="App">
{ loading amp;amp; <p>{loading}</p> }
{ quote amp;amp; <p>"{quote}"</p> }
{ error amp;amp; <p>{error}</p> }
</div>
);
}
export default App;
Ответ №3:
Вы можете использовать функцию более высокого порядка (функцию, которая принимает в качестве аргумента другую функцию), чтобы повторно использовать общие функции загрузки и ошибок. Это очень похоже на шаблон декоратора. Например:
const doSomething = withLoadingAndErrorHandling(Backend.post, this.setState);
function withLoadingAndErrorHandling(fn, setState) {
return async function(...args) {
try {
setState({loading: true});
var result = await fn(args);
setState({loading: false});
return resu<
} catch(err) {
setState({error: err});
}
}
}