На этот раз я полностью закончил useReducer - использование статей

React.js
На этот раз я полностью закончил useReducer - использование статей

useReducer-Основные понятия

useReducer-использовать статьи

useReducer — используется с useContext

В первой статье мы представили редюсер в JavaScript и некоторые его характеристики, те, кто не знаком с редуктором, могут сначала ознакомиться.первый раз.

React HookПосле того, как функция официально выпущена, ей разрешено иметь состояние и побочные эффекты (useEffect) в функциональном компоненте. Официальный предоставляет два хука управления состоянием: useState и useReducer. Ниже мы рассмотрим серию демонстраций, чтобы шаг за шагом объяснить, как использовать useReducer для управления состоянием.

вход в версию useState

Давайте сначала посмотрим на обычное использование страницы входаuseStateреализация:

    function LoginPage() {
        const [name, setName] = useState(''); // 用户名
        const [pwd, setPwd] = useState(''); // 密码
        const [isLoading, setIsLoading] = useState(false); // 是否展示loading,发送请求中
        const [error, setError] = useState(''); // 错误信息
        const [isLoggedIn, setIsLoggedIn] = useState(false); // 是否登录

        const login = (event) => {
            event.preventDefault();
            setError('');
            setIsLoading(true);
            login({ name, pwd })
                .then(() => {
                    setIsLoggedIn(true);
                    setIsLoading(false);
                })
                .catch((error) => {
                    // 登录失败: 显示错误信息、清空输入框用户名、密码、清除loading标识
                    setError(error.message);
                    setName('');
                    setPwd('');
                    setIsLoading(false);
                });
        }
        return ( 
            //  返回页面JSX Element
        )
    }

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

вход в версию useReducer

Давайте посмотрим, как использовать useReducer для преобразования этого кода, сначала кратко представив useReducer.

    const [state, dispatch] = useReducer(reducer, initState);

useReducerПринимает два параметра:

Первый параметр: функция редьюсера, которую мы представили в прошлой статье. Второй параметр: инициализированное состояние. Возвращаемое значение — это последнее состояние и функция отправки (используется для запуска функции редуктора для вычисления соответствующего состояния). Согласно официальному заявлению: для сложной логики работы с состоянием и вложенных объектов состояния рекомендуется useReducer.

Звучит абстрактно, давайте рассмотрим простой пример:

    // 官方 useReducer Demo
    // 第一个参数:应用的初始化
    const initialState = {count: 0};

    // 第二个参数:state的reducer处理函数
    function reducer(state, action) {
        switch (action.type) {
            case 'increment':
              return {count: state.count + 1};
            case 'decrement':
               return {count: state.count - 1};
            default:
                throw new Error();
        }
    }

    function Counter() {
        // 返回值:最新的state和dispatch函数
        const [state, dispatch] = useReducer(reducer, initialState);
        return (
            <>
                // useReducer会根据dispatch的action,返回最终的state,并触发rerender
                Count: {state.count}
                // dispatch 用来接收一个 action参数「reducer中的action」,用来触发reducer函数,更新最新的状态
                <button onClick={() => dispatch({type: 'increment'})}>+</button>
                <button onClick={() => dispatch({type: 'decrement'})}>-</button>
            </>
        );
    }

Поняв основы использования useReducer, давайте посмотрим, как использовать useReducer для преобразования приведенной выше демонстрации входа в систему:

    const initState = {
        name: '',
        pwd: '',
        isLoading: false,
        error: '',
        isLoggedIn: false,
    }
    function loginReducer(state, action) {
        switch(action.type) {
            case 'login':
                return {
                    ...state,
                    isLoading: true,
                    error: '',
                }
            case 'success':
                return {
                    ...state,
                    isLoggedIn: true,
                    isLoading: false,
                }
            case 'error':
                return {
                    ...state,
                    error: action.payload.error,
                    name: '',
                    pwd: '',
                    isLoading: false,
                }
            default: 
                return state;
        }
    }
    function LoginPage() {
        const [state, dispatch] = useReducer(loginReducer, initState);
        const { name, pwd, isLoading, error, isLoggedIn } = state;
        const login = (event) => {
            event.preventDefault();
            dispatch({ type: 'login' });
            login({ name, pwd })
                .then(() => {
                    dispatch({ type: 'success' });
                })
                .catch((error) => {
                    dispatch({
                        type: 'error'
                        payload: { error: error.message }
                    });
                });
        }
        return ( 
            //  返回页面JSX Element
        )
    }

На первый взгляд измененный код useReducer длиннее, но очевидно, что вторая версия имеет лучшую читаемость, а также мы можем более четко понять логику изменения состояния.

Видно, что функция входа в систему теперь более четко выражает намерение пользователя и начинает входить в систему с входа в систему, успешного входа в систему и ошибки входа. LoginPage не нужно заботиться о том, как справляться с такого рода поведением, это то, о чем должен заботиться loginReducer, разделение производительности и бизнеса.

Другим преимуществом является то, что вся обработка состояния централизована, так что у нас есть больший контроль над изменениями состояния, а также проще повторно использовать код изменения логики состояния.Например, в других функциях состояние ошибки входа должно быть вызвано, просто нужноdispatch({ type: 'error' }).

useReducer позволяет намwhatа такжеhowотдельный. Например, если нажата кнопка входа в систему, все, что нам нужно сделать, это инициировать операцию входа в систему.dispatch({ type: 'login' }), нажмите кнопку выхода, чтобы начать операцию выходаdispatch({ type: 'logout' }), все иhowСоответствующий код поддерживается в редюсере, а компонентам нужно только думатьWhat, чтобы наш код был таким же понятным, как и поведение пользователя.

Кроме того, есть еще одно преимущество.Мы упоминали, что Reducer на самом деле является чистой функцией, которая не имеет ничего общего с пользовательским интерфейсом.Решение useReducer заключается в том, что нам проще создавать автоматизированные тестовые случаи.

Суммировать

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

  • если вашstateэто массив или объект
  • если вашstateИзменения очень сложны, часто операция требует изменения большого количества состояний.
  • Если вы хотите создавать автоматизированные тест-кейсы для обеспечения стабильности программы
  • Если вам нужно изменить какое-то состояние в глубоких подкомпонентах (мы подробно расскажем об этом в следующей статье)
  • Если вы используете относительно большое приложение, вы надеетесь, что пользовательский интерфейс и бизнес можно поддерживать отдельно.

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

Если кто из вас виделthinking-in-reactМогут возникнуть сомнения, а разве не официальная рекомендация о том, что государство должно иметь подкомпоненты на самообслуживании, почему оно должно быть централизованным?

На самом деле, мы не рекомендуем объединять все состояния, но если действительно есть много состояний, которые являются общими для нескольких компонентов и должны поддерживаться на уровне страницы, то на данном этапе можно рассмотреть возможность использования useReducer.

PS: порекомендуйте две статьи об управлении состоянием в React.

Последняя практика, приветствуем всех, чтобы отметить нашуБлог фронтенд-команды Renrendai, все статьи также будут обновляться синхронно сЗнай колонкуа такжеСчет наггетс, мы еженедельно делимся несколькими высококачественными техническими статьями о внешнем интерфейсе. Если вам понравилась эта статья, я надеюсь, что вы можете поставить палец вверх.

Ссылка на ссылку