Как обновить пользовательское значение ловушки - PullRequest
1 голос
/ 20 апреля 2020

Я начал изучать машинопись и реагировать на мои новые веб-проекты. У меня есть некоторые проблемы с управлением начальным значением моего пользовательского хука, который я сделал. Не могу перешагнуть через эту функциональность. Как я должен обновить nameInput hook после получения данных из моего API. Например, если я передаю пользовательскую строку в качестве начального значения в useTextInput все в порядке, но проблема в том, что сначала я передаю туда неопределенное значение (когда данные выбираются из API), а значение после загрузки и кажется, что он не обновляется.

Мой вопрос заключается в том, как правильно обновить значение inputValue AccountInput значением, полученным из API как userAccount.firstName из метода getUser (), ведьма зависит от nameInput, а ведьма - нет обновляется после начального значения в useTextInput.

Account.tsx

import React, { useEffect, useState} from 'react';
import { connect } from 'react-redux';
import { IApplicationState } from '../../store';
import { actionCreators, reducer, AccountStatusEnum } from '../../store/Account';
import { MDBBtn, MDBInput } from 'mdbreact';
import { AccountInput } from './child-components';
import { useTextInput } from '../../hooks';

type AccountProps = ReturnType<typeof reducer> & typeof actionCreators;

const Account: React.FC<AccountProps> = ({ getUser, resetState, userAccount, status }) => {
    const nameInput = useTextInput(userAccount.firstName);
    const [isInputInvalid, setIsInputInvalid] = useState<boolean>(false);
    useEffect(() => {
        getUser();
    }, []);

        return (
            <React.Fragment>
                <div className="mt-3 container border border-light">
                    <h5 className="secondary-heading font-weight-bold pt-3 pl-5">User info</h5>
                    <div className="row">
                        <AccountInput
                            textInput={nameInput}
                            typeInput="text"
                            labelInput="Your name & surename"
                            isInputInvalid={isInputInvalid}
                        />
                    </div>
                </div>
            </React.Fragment>
        );
};

const mapStateToProps = (state: IApplicationState) => state.acc;

export default connect(mapStateToProps, actionCreators)(Account as any);

AccointInput.tsx

import React, { Fragment, useEffect, useState } from 'react';
import { TextInput } from '../../../hooks';
import { MDBInput } from 'mdbreact';

type AccountInputProps = {
    readonly textInput: TextInput;
    readonly isInputInvalid: boolean;
    readonly typeInput: string;
    readonly labelInput: string;
};

const AccountInput = React.memo<AccountInputProps>(({ textInput, isInputInvalid, typeInput, labelInput }) => {
    const { hasValue, bindToInput } = textInput;
    return (
        <Fragment>
            <div className="col-sm w-100 px-5">
                <MDBInput hint={textInput.value} {...bindToInput} type={typeInput} label={labelInput} />
            </div>
        </Fragment>
    );

});

AccountInput.displayName = 'AccountInput';

export default AccountInput;

useTextInput.ts

import { useState, useCallback, useMemo, FormEvent } from 'react';

export type TextInputType = 'text' | 'password';

export type TextInput = {
    value: string;
    hasValue: boolean;
    clear: () => void;
    bindToInput: {
        value: string;
        type: TextInputType;
        onChange: (e: FormEvent<HTMLInputElement>) => void;
    };
};

export const useTextInput = (initial: string = '', type: TextInputType = 'text'): TextInput => {
    const [value, setValue] = useState<string>(initial);
    const clear = useCallback((): void => setValue(''), []);
    const onChange = useCallback((e: FormEvent<HTMLInputElement>): void => setValue(e.currentTarget.value), []);

    return useMemo<TextInput>(
        () => ({
            value,
            clear,
            hasValue: !!(value && value.trim()),
            bindToInput: {
                type,
                value,
                onChange,
            },
        }),
        [value, type, onChange, clear],
    );
};

1 Ответ

1 голос
/ 20 апреля 2020

Я не знаю точно, как пользовательские хуки обрабатывают обещания, но обычно, когда вы хотите передать значение async в useState, вы делаете что-то вроде этого:

const useTextInput = (initial) => {
  const [value, setValue] = useState(initial);

  useEffect(() => {
    setValue(initial);
  }, [initial]);
};

Вы можете использовать useEffect для обновления значения состояния при изменении initial. Будет ли это работать в вашем случае?

...