使用 React Hook 处理输入

我发现有几种方法可以用钩子来处理用户的文本输入。用钩子处理输入的更好或更正确的方法是什么?你会用哪个?

1)最简单的钩子来处理输入,但是你有更多的字段,你必须写更多的重复代码。

const [username, setUsername] = useState('');
const [password, setPassword] = useState('');

活动:

onChange={event => setPassword(event.target.value)}
onChange={event => setUsername(event.target.value)}

2)类似上面的例子,但使用动态键名

const [inputValues, setInputValues] = useState({
username: '', password: ''
});


const handleOnChange = event => {
const { name, value } = event.target;
setInputValues({ ...inputValues, [name]: value });
};

事件:

onChange={handleOnChange}

3) useState的替代品,正如 ReactJS 文档中所说,useReducer通常比 useState更可取。

const [inputValues, setInputValues] = useReducer(
(state, newState) => ({ ...state, ...newState }),
{username: '', password: ''}
);


const handleOnChange = event => {
const { name, value } = event.target;
setInputValues({ [name]: value });
};

事件:

onChange={handleOnChange}

4) useCallback将返回回调函数的制表版本,该版本只有在其中一个依赖项发生变化时才会发生变化。

const [inputValues, setInputValues] = useState({
username: '', password: ''
});


const handleOnChange = useCallback(event => {
const { name, value } = event.target;
setInputValues({ ...inputValues, [name]: value });
});

事件:

onChange={handleOnChange}
232188 次浏览

我是这样做的(假设您的输入必须在表单中) :

我使用了一个 BasicForm 组件。

它将所有输入状态存储到一个对象中的一个 useState ()调用中。

它通过 useContext()传递 inputs状态以及 onChange()函数和 setInputInitialState()函数,以便在输入第一次安装时设置其初始状态。它还传递 onFocus 和 onBlur,并且它有验证字段的函数,我在这里没有展示这些函数来简化代码。

通过这种方式,我可以很容易地创建一个包含任意多输入的表单,比如:

<BasicForm
isSubmitting={props.isSubmitting}
submitAction={ (formState) =>
props.doSignIn(formState) }
>
<TextInput
type='email'
label='Email'
name='email'
placeholder='Enter email...'
required
/>
<TextInput
type='password'
label='Password'
name='password'
placeholder='Enter password...'
min={6}
max={12}
required
/>
<SubmitButton
label='Login'
/>
</BasicForm>

BasicForm.js

import FormContext from './Parts/FormContext';


function BasicForm(props) {


const [inputs, setInputs] = useState({});


function onChange(event) {
const newValue = event.target.value;
const inputName = event.target.name;
setInputs((prevState)=> {
return({
...prevState,
[inputName]: {
...prevState[inputName],
value: newValue,
dirty: true
}
});
});
}


function setInputInitialState(
inputName,
label='This field ',
type,
initialValue = '',
min = false,
max = false,
required = false) {


const INITIAL_INPUT_STATE = {
label: label,
type: type,
onFocus: false,
touched: false,
dirty: false,
valid: false,
invalid: false,
invalidMsg: null,
value: initialValue,
min: min,
max: max,
required: required
};


setInputs((prevState) => {
if (inputName in prevState) {
return prevState;
}
return({
...prevState,
[inputName]: INITIAL_INPUT_STATE
});
});


}


return(
<FormContext.Provider value=\{\{
onChange: onChange,
inputs: inputs,
setInputInitialState: setInputInitialState,
}}>
<form onSubmit={onSubmit} method='POST' noValidate>
{props.children}
</form>
</FormContext.Provider>
);
}

TextInput.js

输入使用 useEffect()挂钩来设置挂载时的初始状态。

function TextInput(props) {


const formContext = useContext(FormContext);


useEffect(() => {
console.log('TextInput useEffect...');
formContext.setInputInitialState(
props.name,
props.label,
props.type,
props.initialValue,
props.min,
props.max,
props.required
);
},[]);


return(
<input
type={props.type}
id={props.name}
name={props.name}
placeholder={props.placeholder}
value={([props.name] in formContext.inputs) ?
formContext.inputs[props.name].value
: props.initialValue || ''}
onChange={formContext.onChange}
onFocus={formContext.onFocus}
onBlur={formContext.onBlur}
>
</input>
</div>
{([props.name] in formContext.inputs) ?
formContext.inputs[props.name].invalidMsg && <div><span> {formContext.inputs[props.name].invalidMsg}</span></div>
: null}
</div>
);


...
}

写一个返回输入值的可重用函数怎么样... ... 还有 <input>本身:

 function useInput({ type /*...*/ }) {
const [value, setValue] = useState("");
const input = <input value={value} onChange={e => setValue(e.target.value)} type={type} />;
return [value, input];
}

然后可以用作:

 const [username, userInput] = useInput({ type: "text" });
const [password, passwordInput] = useInput({ type: "text" });


return <>
{userInput} -> {username} <br />
{passwordInput} -> {password}
</>;

是的,您可以使用 useState ()处理反应挂钩

import React, {useState} from 'react'


export default () => {
const [fName, setfName] = useState('');
const [lName, setlName] = useState('');
const [phone, setPhone] = useState('');
const [email, setEmail] = useState('');


const submitValue = () => {
const frmdetails = {
'First Name' : fName,
'Last Name' : lName,
'Phone' : phone,
'Email' : email
}
console.log(frmdetails);
}


return(
<>
<hr/>
<input type="text" placeholder="First Name" onChange={e => setfName(e.target.value)} />
<input type="text" placeholder="Last Name" onChange={e => setlName(e.target.value)} />
<input type="text" placeholder="Phone" onChange={e => setPhone(e.target.value)} />
<input type="text" placeholder="Email" onChange={e => setEmail(e.target.value)} />
<button onClick={submitValue}>Submit</button>
</>
)
}

我现在就是这么用的:

const [inputValue, setInputValue] = React.useState("");


const onChangeHandler = event => {
setInputValue(event.target.value);
};


<input
type="text"
name="name"
onChange={onChangeHandler}
value={inputValue}
/>
function App(){
const [name, setName] = useState("");
const [istrue, Setistrue] = useState(false);
const [lastname,setLastname]=useState("");
    

function handleclick(){
Setistrue(true);
}
    

return(
<div>
{istrue ? <div> <h1>{name} {lastname}</h1> </div> :
<div>
<input type="text" placeholder="firstname" name="name" onChange={e =>setName(e.target.value)}/>
<input type="text" placeholder="lastname" name="lastname" onChange={e =>setLastname(e.target.value)}/>
<button  type="submit" onClick={handleclick}>submit</button>
</div>}
</div>
)
    

}


}

您可能需要考虑像 Formik这样的表单库