Я слышал, что вы используете useState из-за головной боли асинхронного обновления? попробуй использоватьReducer

React.js

В последнее время проект непрерывно итерируется, и работа не останавливается, я сталкивался с большими и маленькими проблемами, но, к счастью, они постепенно решались. Давно не записывал проблему, вот и взял.

В разработке есть требование, чтобы несколько интерфейсов вызывались циклически, а вызовы интерфейсов вызывались по-разному в соответствии с разными операциями пользователя, но в итоге все полученные данные должны быть сохранены для обновления представления. Например следующее:

я каштан

 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

Часть жизни — это работа, часть работы — решать проблемы, чтобы радовать жизнь, так что живите хорошо, хорошо работайте и хорошо любите (●ˇ∀ˇ●)