我已经开始学习打字稿,并对新的Web项目做出反应。我在管理自己制作的自定义钩子的初始值时遇到一些问题。无法胜任此功能。从API提取数据后,应如何更新 nameInput 挂钩。例如,如果我在 useTextInput 中将自定义字符串作为初始值传递,那么一切都很好,但是问题是当我首先传递未定义的值(从API提取数据时)和传递后的值时已下载,似乎没有更新。
我的问题是,如何通过getUser()方法中的API作为userAccount.firstName来自API的值来正确更新AccountInput inputValue值,而女巫依赖于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],
);
};
答案 0 :(得分:2)
我不确定自定义钩子如何处理承诺,但是通常当您要将async
值传递给useState
时,您会执行以下操作:
const useTextInput = (initial) => {
const [value, setValue] = useState(initial);
useEffect(() => {
setValue(initial);
}, [initial]);
};
当useEffect
更改时,您可以使用initial
更新状态值。这种情况适合您吗?