当前位置: 首页 > 知识库问答 >
问题:

仅在第一次use效应提取已触发并在上下文中设置用户后运行use效应提取

郎翔
2023-03-14

我需要调用dropbox api两次。第一个useffect获取名称和路径,然后将它们推送到上下文中的空白数组中。然后我需要激发第二个useEffect,它依赖于从第一个useEffect填充的数组。我尝试使用state并创建loading和setload,然后将useffect的内部封装在和if(loading)中,但这不起作用,因为我猜它只会在安装组件时尝试触发。第一个useEffect完成后,如何运行第二个useEffect?

const [user, setUser] = useContext(UserContext);

第一次使用效果:

useEffect(() => {
    var myHeaders = new Headers();
    myHeaders.append(
      'Authorization',
      'Bearer XXXXXXXXXXXXXXX',
    );
    myHeaders.append('Content-Type', 'application/json');

    var raw = JSON.stringify({path: `/${user.username}`});

    var requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: raw,
      redirect: 'follow',
    };

    fetch('https://api.dropboxapi.com/2/files/list_folder', requestOptions)
      .then(response => response.json())
      .then(data => {
        let tmpArray = [];
        let tmpArrayTwo = [];
        for (var i = 0; i < data.entries.length; i++) {
          tmpArray.push(data.entries[i].name);
          tmpArrayTwo.push(data.entries[i].path_lower);
        }
        setUser({
          ...user,
          imageNames: tmpArray,
          imagePaths: tmpArrayTwo,
        });
      })
      .catch(error => console.log('error', error));
  }, []);

第二次使用效果:

useEffect(() => {
    let tmpArray = [];
    var myHeaders = new Headers();
    myHeaders.append(
      'Authorization',
      'Bearer XXXXXXXXXXXXXX',
    );
    myHeaders.append('Content-Type', 'application/json');

    for (var i = 0; i < user.imagePaths.length; i++) {
      var raw = JSON.stringify({path: `/${user.imagePaths[i]}`});
      var requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: raw,
        redirect: 'follow',
      };
      fetch(
        'https://api.dropboxapi.com/2/files/get_temporary_link',
        requestOptions,
      )
        .then(response => response.json())
        .then(data => {
          tmpArray.push(data.link);
        })
        .catch(error => console.log('error', error));
    }
    console.log(tmpArray);
    setUser({
      ...user,
      imageLinks: tmpArray,
    });
  }, []);

我认为它与依赖数组有关,但我在其中放入的所有内容(如user、setUser)都给了我一个无限循环和控制台。用户的日志。imagePaths保持日志记录为[]。我认识用户。ImagePath在第一个useEffect之后填充,但是第二个useEffect对于用户来说一直是未定义的。图像路径。循环的长度。

共有2个答案

丌官向荣
2023-03-14

据我所知。我建议您首先使用状态,以便使您的数据处于React的生命周期中。

const [listFolders, setListFolders] = React.useState([])
const [user, setUser] = React.useState({})

您的第一个use效应将加载到组件的第一个挂载上,并且在函数结束时的[]位置之后不会得到回调。这允许告诉React仅在无依赖时触发效果。

useEffect(() => {
   ...
}, [])

仅当阵列listFolders更改时,才会加载第二个useEffect。除此之外,这里的目标是连接您的所有promise,以便它只更新用户一次。否则我们将有异步的问题。

useEffect(() => {
   if(listFolders.length){

      Promise.all([*put all your promise here*]).then((data) => {
          * concatenate your array of link
          setUser({
             ...user,
             imageLinks: arrayOfLinks,
          })
      })
    }
}, [listFolders])
盖和泰
2023-03-14

您应该添加用户。第二个useEffect的依赖项列表的ImagePath。

我建议使用async/wait并在单一使用效果中进行调用。

如果默认情况下用户未定义,那么您可能需要添加可选的链接。

[更新]

尝试改变第二个使用效果:

useEffect(() => {
    var myHeaders = new Headers();
    myHeaders.append(
        'Authorization',
        'Bearer XXXXXXXXXXXXXX',
    );
    myHeaders.append('Content-Type', 'application/json');

    if (!user?.imagePaths) {
        return;
    }

    Promise.all(user.imagePaths.map(path => {
        var raw = JSON.stringify({path: `${path}`});
        var requestOptions = {
          method: 'POST',
          headers: myHeaders,
          body: raw,
          redirect: 'follow',
        };
        return fetch(
          'https://api.dropboxapi.com/2/files/get_temporary_link',
          requestOptions,
        )
          .then(response => response.json())
          .then(data => data.link)
          .catch(error => console.log('error', error));
      }),
    ).then(imageLinks => {
      setUser({
        ...user,
        imageLinks,
      });
    });
  }, [user?.imagePaths]);
 类似资料:
  • 因此,我有一些代码并没有像预期的那样工作。当前焦点是在父组件上使用useState()设置的,因此它是一个状态变量。但是,当父级中的currentFocus值更改时,此处的focus变量本身不会更新。我希望重新呈现父组件,这反过来会重新呈现该组件,从而导致foucs值发生更改。 现在我可以通过执行以下操作来解决此问题, 但我只想在更新focus/currentFocus时运行useEffect挂钩

  • 我正在尝试将基于类的组件转换为功能组件。如果在useEffect钩子中使用与componentDidMount下相同的代码,则会出现上述错误。 以下是发生错误的功能组件 抛出以下错误,浏览器崩溃未捕获(promise)错误:重新渲染过多。React限制渲染的数量以防止无限循环。

  • 现在我每10秒调用一个间隔函数。我的问题是在使用效果我有一个依赖数组,有通道ID。那么,当组件卸载时,是否会调用这个clearInterval函数?

  • 当状态更改时,组件的更新程度如何?比方说,当状态A发生变化时,我可以读取render in组件的控制台日志。我想知道useState语句会发生什么情况,因为初始值设置为1,因为不应该忽略初始值。当我调用某个函数时,a现在变为2,但如果发生重新排序,const[a,setA]=useState(1)会发生什么情况? 对于useEffect,当状态A发生变化时,我还认为useEffect会被重新声明(

  • 运行时运行case 0时,我一直收到java.lang.NullPointerException。该问题似乎与设置TextField的提示文本有关。但是,当我切换选项卡时,问题不会返回。GUI是在Scene Builder中构建的。如何将TextField初始化为非空值。 这是准确的错误代码 我的FXML文件 FXML文件确实附加了正确的控制器

  • 设置笔触宽度并应用效果 在控制面板中找到笔触部分。如果单击笔触文本链接,则可以打开笔触菜单以精确设置单个笔触粗细和各个笔触的对齐方式。使用该链接右侧的颜色选取器,可以设置笔触的颜色,而右侧的数值字段可供设置笔触的整个宽度。 将现有的默认笔触宽度 1 更新为 0(这样就不会显示笔触)。单击向下箭头键或在“笔触宽度”字段中选择默认值 1,然后键入 0 以设置零宽度的笔触。 在控制面板的右侧,找到效果文