React-Redux场景下myPetArray有元素但length始终返回0问题求解
问题根因
- 异步请求时序不匹配:
dispatch(getPetListByUserId(userId))触发的是异步接口请求,dispatch执行后不会立即更新Redux中的myPetArray,首次执行useEffect逻辑时读取的是myPetArray的初始空数组值 - 按钮状态更新逻辑不全:当前仅判断了
myPetArray.length === 0的场景设置禁用状态,当myPetArray更新为非空数组时,没有对应逻辑解除按钮禁用,导致状态一直停留在禁用态 - 冗余状态维护:按钮禁用状态完全可以通过myPetArray直接派生,不需要单独用useState维护,多一层状态转换反而容易出现同步错误
修复方案
方案1:极简优化(推荐)
直接删除多余的nextButton状态,通过myPetArray直接控制按钮禁用属性:
const dispatch = useDispatch() // 从state中提取myPetArray对应片段 const petListByUserId = useSelector((state) => state.petListByUserId) const { myPetArray, myPetArraySuccess } = petListByUserId useEffect(() => { dispatch(getPetListByUserId(userId)) }, [userId, dispatch]) // 直接派生禁用状态:数组长度为0时禁用 <Button disabled={myPetArray?.length === 0}>Next Step</Button>
如果需要考虑请求未返回的中间态,可结合接口成功标识判断,避免误操作:
<Button disabled={!myPetArraySuccess || myPetArray?.length === 0}>Next Step</Button>
方案2:修复现有状态逻辑
如果一定要保留useState维护按钮状态,补全判断分支即可:
const dispatch = useDispatch() const [nextButton, setNextButton] = useState(false) const petListByUserId = useSelector((state) => state.petListByUserId) const { myPetArray, myPetArraySuccess } = petListByUserId useEffect(() => { dispatch(getPetListByUserId(userId)) }, [userId, dispatch]) // 单独监听myPetArray变化更新按钮状态 useEffect(() => { if (myPetArray) { setNextButton(myPetArray.length === 0) } }, [myPetArray]) <Button disabled={nextButton}>Next Step</Button>
内容的提问来源于stack exchange,提问作者Aliking66
相关产品推荐
相关产品推荐

