Javascript 反应组件isn';t根据异步调用的响应进行更新

Javascript 反应组件isn';t根据异步调用的响应进行更新,javascript,reactjs,Javascript,Reactjs,我的应用程序页面侧面有一张组件卡,显示用户当前的健身轨迹: 页面加载时,曲目名称为空,因为尚未从服务器加载。但是,我希望它会在返回结果后立即更新组件并重新加载。同样,当您单击组件的箭头时,会弹出一个模态,询问您是否准备好前进到下一个轨迹。如果您确认,它将调用调用API的switchTrack()函数,如果结果成功,则更新用户并关闭模式。但是,即使该曲目实际上已经更新,在刷新页面之前,曲目名称不会刷新。当结果返回时,我如何确保此组件使用新文本重新加载?(注意:您将看到我尝试使用重新加载状态强制执

我的应用程序页面侧面有一张组件卡,显示用户当前的健身轨迹:

页面加载时,曲目名称为空,因为尚未从服务器加载。但是,我希望它会在返回结果后立即更新组件并重新加载。同样,当您单击组件的箭头时,会弹出一个模态,询问您是否准备好前进到下一个轨迹。如果您确认,它将调用调用API的
switchTrack()
函数,如果结果成功,则更新用户并关闭模式。但是,即使该曲目实际上已经更新,在刷新页面之前,曲目名称不会刷新。当结果返回时,我如何确保此组件使用新文本重新加载?(注意:您将看到我尝试使用重新加载状态强制执行此操作,但此操作不起作用)

元件卡(简化):

const CurrentPlanCard=props=>{
const{open,launchModal,closeModal}=useModal(false);
const{user}=useSelector(mapState);
常量[currentTrackName,setCurrentTrackName]=useState(“”);
const[nextTrackName,setNextTrackName]=useState(“”);
const[nextTrackId,setNextTrackId]=useState(“”);
const[reload,setReload]=useState(false);
useffect(()=>{
如果(用户){
getTrack(user.fitnessTrack)
。然后(currentTrack=>{
setCurrentTrackName(currentTrack.name);
setNextTrackName(currentTrack?.nextTrack.name);
setNextTrackId(currentTrack?.nextTrack.\u id);
})
.catch(错误=>{
控制台错误(err);
});
}
},[user,reload,setCurrentTrackName,setNextTrackName,setNextTrackId];
返回(
当前健身路线:
{currentTrackName}
准备好进入下一阶段了吗?现在切换您的计划!
);
};
切换计划的模式:

const SwitchPlanModal = ({
  open,
  handleClose,
  userId,
  currentTrackName,
  nextTrackName,
  nextTrackId,
  setReload,
  reload,
  ...props
}) => {
  const [error, setError] = useState('');
  const handleClick = async e => {
    try {
      if (nextTrackId) {
        await switchTrack(userId, nextTrackId);
        setReload(!reload);
        setError('');
        handleClose();
      } else {
        setError('No next track defined');
      }
    } catch (err) {
      console.error(err);
      if (err.message) {
        setError(err.message);
      } else if (err.error.message) {
        setError(err.error.message);
      }
    }
  };

  return (
    <div>
      <Modal open={open} onClose={handleClose}>
        <StyledDialogContent>
          <Container justify="center" flexDirection="column">
            <NavBar justify="space-between" alignItems="center">
              <CloseRight>
                <CloseIcon handleClose={handleClose} />
              </CloseRight>
            </NavBar>
            <ModalBody
              justify="space-evenly"
              alignItems="center"
              flexDirection="column"
            >
              <StyledAvatar src={`${fileStorage}/AddExercise.png`} />
              <FlexContainer flexDirection="column" alignItems="center">
                <Header>Ready for the next stage?</Header>
              </FlexContainer>
              <FlexContainer flexDirection="column" alignItems="center">
                <Button
                  buttonText="Let's Go!"
                  onClick={handleClick}
                />
                <Link onClick={handleClose}>Nope, not yet</Link>
                {error && <ErrorMessage>{error}</ErrorMessage>}
              </FlexContainer>
            </ModalBody>
          </Container>
        </StyledDialogContent>
      </Modal>
    </div>
  );
};
const switchplanmodel=({
打开
手镯,
用户ID,
currentTrackName,
nextTrackName,
nextTrackId,
设置重新加载,
重新加载
…道具
}) => {
const[error,setError]=useState(“”);
const handleClick=async e=>{
试一试{
如果(nextTrackId){
等待切换跟踪(userId,nextTrackId);
setReload(!reload);
设置错误(“”);
handleClose();
}否则{
setError(“未定义下一个曲目”);
}
}捕捉(错误){
控制台错误(err);
如果(错误消息){
设置错误(错误消息);
}else if(err.error.message){
setError(err.error.message);
}
}
};
返回(
准备好进入下一阶段了吗?
不,还没有
{error&&{error}
);
};

旁注:您不需要在
useffect
dep中放置任何状态设置器。
useState
中的setter函数在组件的整个生命周期内都是稳定的。eslint的穷举deps规则似乎认为我需要它们。我使用该规则,它知道对于
useState
setter,最好不要坚持使用该规则。我不知道你为什么会听到另一种说法。
const SwitchPlanModal = ({
  open,
  handleClose,
  userId,
  currentTrackName,
  nextTrackName,
  nextTrackId,
  setReload,
  reload,
  ...props
}) => {
  const [error, setError] = useState('');
  const handleClick = async e => {
    try {
      if (nextTrackId) {
        await switchTrack(userId, nextTrackId);
        setReload(!reload);
        setError('');
        handleClose();
      } else {
        setError('No next track defined');
      }
    } catch (err) {
      console.error(err);
      if (err.message) {
        setError(err.message);
      } else if (err.error.message) {
        setError(err.error.message);
      }
    }
  };

  return (
    <div>
      <Modal open={open} onClose={handleClose}>
        <StyledDialogContent>
          <Container justify="center" flexDirection="column">
            <NavBar justify="space-between" alignItems="center">
              <CloseRight>
                <CloseIcon handleClose={handleClose} />
              </CloseRight>
            </NavBar>
            <ModalBody
              justify="space-evenly"
              alignItems="center"
              flexDirection="column"
            >
              <StyledAvatar src={`${fileStorage}/AddExercise.png`} />
              <FlexContainer flexDirection="column" alignItems="center">
                <Header>Ready for the next stage?</Header>
              </FlexContainer>
              <FlexContainer flexDirection="column" alignItems="center">
                <Button
                  buttonText="Let's Go!"
                  onClick={handleClick}
                />
                <Link onClick={handleClose}>Nope, not yet</Link>
                {error && <ErrorMessage>{error}</ErrorMessage>}
              </FlexContainer>
            </ModalBody>
          </Container>
        </StyledDialogContent>
      </Modal>
    </div>
  );
};