В последнее время проект непрерывно итерируется, и работа не останавливается, я сталкивался с большими и маленькими проблемами, но, к счастью, они постепенно решались. Давно не записывал проблему, вот и взял.
В разработке есть требование, чтобы несколько интерфейсов вызывались циклически, а вызовы интерфейсов вызывались по-разному в соответствии с разными операциями пользователя, но в итоге все полученные данные должны быть сохранены для обновления представления. Например следующее:
я каштан
const [result, setResult] = useState({});
const fetchList = () => {
serviceList.map(async (item) => {
const response = await item.service();
// 在每次获取到数据后setState,存到状态中
setResult({ ...result, [item.key]: response });
});
};
Приведенное выше — всего лишь простой пример, а реальная сцена, как правило, сложнее, чем эта. На первый взгляд в этом нет ничего плохого, но проблема в том, что после выполнения вышеуказанногоfetch
После метода полученный статус результата - это вообще не совокупность всех результатов, а последнее обновление...
первая неудачная попытка
Это сложно сделать, потому что сам хук setState реакции наследует предыдущий метод setState, поэтому он, естественно, асинхронный, цель — повысить производительность и избежать ненужных обновлений.
Как умный кирпичный движитель может быть поставлен в тупик такой маленькой насыпью, поэтому я придумал способ сначала определить временную переменную вне цикла для хранения всех результатов, а затем присвоить их единообразно результату, поэтому есть следующий вариант :
const [result, setResult] = useState({});
const fetchList = () => {
let nowResult;
serviceList.map(async (item) => {
const response = await item.service();
// 获取数据后添加到临时变量中更新
nowResult = { ...nowResult, [item.key]: response };
// 记得要更新state,因为这里是异步调用接口,在外面会造成拿不到结果
setResult({ ...result, ...nowResult });
});
};
useReducer успешно разрешен
Проблема решилась, но потом обнаружилась другая проблема,fetch
Он может вызываться много раз при разных обстоятельствах... Так результат первого вызова еще не пришел и обновляется до результата, а второй вызов выполняется по очереди, так что он возвращается к источнику. Но это не может остановить мое увлечение техникой (раздражительность), в случае постоянного гугления, я наконец-то нашел магию useReducer, оказывается его можно не только применять к сложным обновлениям состояния, но и может обновлять состояние синхронно, хвала! Итак, со следующей версией:
const [result, setResult] = useReducer((state, action) => {
switch (action) {
//这里是一个投机的写法,无论action是什么,都按照下面的形式更新state
default:
return { ...state, ...action };
}
}, {});
const fetchList = () => {
serviceList.map(async (item) => {
const response = await item.service();
// 记得要更新state,因为这里是异步调用接口,在外面会造成拿不到结果
setResult({ ...result, [item.key]: response });
});
};
Таким образом, временные переменные больше не нужны, и мир стал лучше (~ ̄▽ ̄)~
Узнайте больше о настоящей любви: useReducer
Кратко представим useReducer, на самом деле я не очень часто использую этот хук, этот хук подходит для обновления сложных переменных.
const [result, setResult] = useReducer((state, action) => {
switch (action) {
case 'action1':
return {...state, result1};//具体更新方法
case 'action2':
return {...state, result2};//具体更新方法
default:
return { ...state, ...action };
}
}, initialState);
Этот хук объявляет, что форма переменной такая же, как у useState, но первая функция, полученная useReducer, принимает состояние и действие в качестве параметров, а внутренняя форма такая же, как и у метода редуктора, определенного ранее с помощью redux. Исходная переменная состояния.Легко ли ее использовать?
Если у вас есть какие-либо вопросы, пожалуйста, укажите, и дайте мне палец вверх, если вы найдете это полезным o( ̄▽ ̄)o
Часть жизни — это работа, часть работы — решать проблемы, чтобы радовать жизнь, так что живите хорошо, хорошо работайте и хорошо любите (●ˇ∀ˇ●)