嗨,我是新来的,当它的长度为6位数时,我正在使用pincode设置状态和城市。当我将整个函数放入useEffect时,包含setPersonalDetState&我也想使用相同的函数来验证我不能将其包含在useEffect 中
const intialState = {
city: '',
state: '',
pincode: ''
};
const PersonalDetails = () => {
const [personalDetState, setPersonalDetState] = useState(intialState);
const { city, state, pincode } = personalDetState;
const fetchPincode = async (pincode) => {
if (pincode.length != 6) {
return;
}
let cityState = await axios.get(
`https://api.postalpincode.in/pincode/${pincode}`
);
const { Status, PostOffice } = cityState.data[0];
const { District, State } = PostOffice[0];
personalDetState['city'] = District;
personalDetState['state'] = State;
return setPersonalDetState({ ...personalDetState });
};
useEffect(() => {
fetchPincode(pincode);
}, [pincode]);
const handleChange = (event) => {
let { value, name } = event.target;
if (name === 'pincode') value = value.replace(/D/g, '');
if (name === 'pincode' && value.length === 7) return;
setPersonalDetState({ ...personalDetState, [name]: value });
};
return (
<Fragment>
<input
type='text'
name='pincode'
value={pincode}
onChange={handleChange}
/>
<input type='text' name='city' value={city} disabled />
<input type='text' name='state' value={state} disabled />
</Fragment>
);
};
您可以将useCallback
指定为fetchPincode
,以便正确地将其指定为效果的依赖项。它将在pincode更改时运行,但由于fetchPincode回调没有依赖项,因此不会触发效果。
const intialState = {
city: '',
state: '',
pincode: ''
};
const PersonalDetails = () => {
const [personalDetState, setPersonalDetState] = useState(intialState);
const { city, state, pincode } = personalDetState;
const fetchPincode = useCallback(() => {
if (pincode.length != 6) {
return;
}
axios.get(
`https://api.postalpincode.in/pincode/${pincode}`
).then(cityState => {
const { Status, PostOffice } = cityState.data[0];
const { District, State } = PostOffice[0];
setPersonalDetState(prev => ({
city: District,
state: State
}));
});
}, [pincode]);
useEffect(fetchPincode, [pincode]);
const handleChange = (event) => {
let { value, name } = event.target;
if (name === 'pincode') value = value.replace(/D/g, '');
if (name === 'pincode' && value.length === 7) return;
setCredentials({ ...userCredentials, [name]: value });
};
return (
<Fragment>
<input
type='text'
name='pincode'
value={pincode}
onChange={handleChange}
/>
<input type='text' name='city' value={city} disabled />
<input type='text' name='state' value={state} disabled />
</Fragment>
);
};
我已经重写了fetchPincode以使用旧的Promise语法,因为它必须不返回任何内容才能用作useEffect回调。我在这里回答了一个类似的问题。
为什么选择useCallback
为了在重新渲染之间保持相同的函数引用。如果函数的依赖项发生变化,则对该函数的引用将发生变化(依赖项被指定为函数后面的数组,作为useCallback的第二个参数(。
为什么使用相同的函数引用因为如果包含为对另一个钩子的依赖项(比如useEffect
(,则更改引用可能会导致效果重新运行(在出现效果的情况下(,如果该函数引用更改太频繁,则可能不需要这样做。
在您的特定情况中,无论何时键入,pincode
都会更改(不能100%确定,但我认为setCredentials
正在执行此操作,我没有看到它的声明(。这将导致对fetchPincode
的函数引用发生更改。如果指定为效果的依赖项,则如果函数ref发生更改,效果将运行但您也将pincode
指定为依赖项,所以效果无论如何都会在每个键输入上运行但您可能会考虑在指定的不活动时间(用户不键入(后发出请求,也称为debounce。
了解挂钩:
- 钩子介绍
- 挂钩常见问题解答