API 调用后 useState 不更新变量

时间:2021-03-10 20:46:19

标签: javascript reactjs typescript next.js use-state

我认为这个问题之前已经有人回答过,但我已经尝试浏览了所有类似标题的问题,但我仍然有点困惑。

我的代码从三词地址 API 请求一些数据,然后使用 setState 为该数据提供一个对象内的变量。但是,它不同步,因此 console.log(modifiedData)slug 显示为空字符串。但是当您再次单击提交按钮时,slug 已更新。

const api = require("@what3words/api");
const [modifiedData, setModifiedData] = useState({
    title: '',
    description: '',
    category: '',
    condition: '',
    capacity: 0,
    slug: '',
    lng: 0,
    lat: 0,
  });
  
const handleSubmit = async e => {
   e.preventDefault();
   api.convertTo3wa({lat: modifiedData.lat, lng: modifiedData.lng}, 'en')
   .then(function(getSlug) {
      setModifiedData((prev) => ({
        ...prev,
        slug: getSlug.words,
      }));
      console.log(modifiedData);
    });

3 个答案:

答案 0 :(得分:1)

这是因为 console.log 具有异步行为,因此您无法保证在执行 reRender 时数据已更新。

您必须等待组件 const [state, setState = useState(..) const submitHandler = (e) =>{ setState({... some data}) console.log(state) //data is not gaurenteed } console.log(state) // first time : {} //second time is the data return( <div> <p>app content </p> </div> ) } 以确保您的数据在那里。

        modelBuilder.Entity<DocketDocket>().HasKey(t => new { t.LeftDocketId, t.RightDocketId });
        modelBuilder.Entity<DocketDocket>().HasOne(m => m.LeftDocket).WithMany(t => t.LeftDockets).HasForeignKey(m => m.LeftDocketId).OnDelete(DeleteBehavior.Restrict);
        modelBuilder.Entity<DocketDocket>().HasOne(m => m.RightDocket).WithMany(t => t.RightDockets).HasForeignKey(m => m.RightDocketId).OnDelete(DeleteBehavior.Restrict);

答案 1 :(得分:1)

很像继承 React.Component 或 React.PureComponent 创建的 Class 组件中的 setState 一样,使用 useState hook 提供的 updater 进行状态更新也是异步的,不会立即反映出来。

看看这个satck overflow question

答案 2 :(得分:0)

就像阿廷说的那样。如果你想用 console.log 看到变化,你可以用 setTimeOut 包装它:

const api = require("@what3words/api");
const [modifiedData, setModifiedData] = useState({
   title: '',
   description: '',
category: '',
condition: '',
capacity: 0,
slug: '',
lng: 0,
lat: 0,
  });
const handleSubmit = async e => {
  e.preventDefault();
  api.convertTo3wa({lat: modifiedData.lat, lng: 
  modifiedData.lng}, 'en')
  .then(function(getSlug) {
  setModifiedData((prev) => ({
    ...prev,
    slug: getSlug.words,
  }));
  setTimeOut(()=>{
   console.log(modifiedData);
  },500)      
});