reactjs 如何使用不同的JSON数据多次调用相同的API

kq0g1dla  于 2023-02-18  发布在  React
关注(0)|答案(2)|浏览(126)

我正在编写一个简单的react页面,其中可以从一个API获取用户详细信息,并在进行一些修改后将其多次传递给另一个API。

export default function User() {
  const [userid, setUserId] = useState("");
  const [userData, setUserData] = useState({});

const synchToLocation=(loc)=>{
    setUserData((userData)=>({...userData,id:1234,location:loc}));
    const requestOptions = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(userData)
    };
    fetch("http://localhost:8080/api/v1/synch" , requestOptions);    
  }

const handleSynch = () => {
    synchToLocation(1);  
    synchToLocation(2);
    synchToLocation(3);
  };

  const fecthUser = (event) => {
    event.preventDefault();
    console.log(userid);
    fetch("http://localhost:8080/api/v1/synch/emp?id=" + userid).then((result) =>
    result.json().then((e) => {          setUserData({...userData,id:e.id,firstName:e.firstName,lastName:e.lastName,role:e.role,location:e.location,status:e.status});
      })
    );
  };

  return (
     <Container>
            <TextField
                id="id"
                label="user id"
                value={userid}
                onChange={(e) => setUserId(e.target.value)}
                fullWidth
                required
              ></TextField>
              <Button
                variant="contained"
                color="secondary"
                type="submit"
                onClick={fecthUser}
              >
                Search
                <SearchOutlined />
              </Button>

         <Box>
            <Button variant="contained" color="secondary" onClick={handleSynch}>
              Synch
            </Button>
          </Box>
    </Container>
);
}

我有一个文本字段和两个按钮(搜索和同步).期望:

  • 如果用户单击搜索按钮,则获取用户输入ID用户数据并设置为状态。
  • 如果用户点击“同步”按钮,用户数据应使用特定位置更新,并使用更新位置调用API。

实际结果:

  • 按预期在搜索时提取用户数据。
  • *API调用旧数据或调用最后更新的数据 *。

请给我建议更好的办法来实现这一点。

o2rvlv0m

o2rvlv0m1#

问题就在这里,因为setState是异步工作的,所以在setUserData之后,请求主体有时会使用旧的userData而不是你之前设置的新userData。

const synchToLocation=(loc)=>{
    setUserData((userData)=>({...userData,id:1234,location:loc}));
    const requestOptions = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(userData)
    };
    fetch("http://localhost:8080/api/v1/synch" , requestOptions);    
  }

您应该将对象的属性体更改为

body:JSON.stringify({...userData,id:1234,location:loc})
vawmfj5a

vawmfj5a2#

Hooks和useEffect()将允许您更新本地状态并基于此更新的状态重新呈现。
参见:https://reactjs.org/docs/hooks-effect.html

const SimpleComp = (userName, fetchUserAPI, fetchLocalParams) => {

const [userData, setUserData] = useState(null);
const [localParams, setLocalParams] = useState(null);

useEffect(() => {
    setUserData( fetchUserAPI(userName) );
}, []);

useEffect(() => {
    setLocalParams( fetchLocalParams(userData) );
  }, [userData]);

return (
    <>UserData: {userData}  localParams: {localParams}</>
    );
};

export default SimpleComp;

两个Hook的初始状态均为null。第一个监视参数([])为空的useEffect()将在加载时调用。第二个useEffect()正在监视Hook:用户数据。当用户数据改变时;将使用更新后的状态调用此useEffect。第一个调用加载时的fetchUserData。这将userData更新为API调用的返回值。这将使用新值设置用户数据。然后将调用第二个useEffect,因为userData-Hook已更改状态。该useEffect调用fetchLocalParametersAPI并将此Hook的值设置为返回的数据。
在所有的useEffects()都被求值之后,Hook状态中的所有这些变化都会触发重新呈现。所有的Hook变量都应该是最新的,并且根据userData呈现localParameters。
如果需要使用同步按钮的方法;然后创建一个onClick,从文本输入设置一个新的userName Hook,并更新userName onClick()。只需创建另一个useEffect,监视userName并使用新的用户名调用fetchUserDataAPI。这将更新userData Hook,当userData更改时,它将调用fetchLocalParams。

相关问题