在 React 中执行 useEffect 时如何选择 [英] how choice when useEffect is executed in React

查看:21
本文介绍了在 React 中执行 useEffect 时如何选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解 useEffect() 在 React 中是如何工作的,以及为什么在最后执行而不是按照我的代码顺序执行.这个问题会导致我更大的程序出现问题.我的问题:是否有可能在执行此操作时进行选择?

控制台的日志,如你所见,不是打印顺序:(

0 个孩子 null App.js:11:102 个孩子 null App.js:16:101个孩子数组[truc";]

https://codesandbox.io/s/busy-cookies-yvq16?file=/src/App.js

我制作这个片段代码来解释我的问题

import "./styles.css";import { useEffect } from "react";让列表 = [];函数缓冲区(){让 init = null;list.push(init);返回<Comp>{list[0]}</Comp>;}函数 Comp({ 孩子 }) {console.log(0 个孩子",孩子);useEffect(() => {儿童 = [truc"];console.log(1 个孩子",孩子们);}, []);console.log(2 个孩子",孩子们);返回<div>超级缓冲区</div>;}导出默认函数 App() {返回 (

<缓冲区/>

);}

解决方案

为什么最后执行的不是我的代码顺序.

因为这是它的目的,这就是它的用途.来自文档:

<块引用>

useEffect

useEffect(didUpdate);

接受一个包含命令式的、可能有效的代码的函数.

在函数组件的主体内部(称为 React 的渲染阶段)不允许突变、订阅、计时器、日志记录和其他副作用.这样做会导致 UI 中出现令人困惑的错误和不一致.

改为使用 useEffect.传递给 useEffect 的函数将在渲染提交到屏幕后运行.将效果视为从 React 的纯函数式世界进入命令式世界的逃生口.

Dan Abramov 的这篇文章也可能有用:A使用效果完整指南.尽管标题如此,但它不仅涵盖了 useEffect,还涵盖了钩子和函数组件的整个工作方式.

<块引用>

有可能选择什么时候执行吗?

从您的问题中并不清楚您想要做什么,但是如果您想立即做某事,请立即执行,而无需任何包装功能.但请记住,每次组件需要重新渲染时,您的组件函数都会运行,因此 useEffect 仅用于运行 A) 组件第一次挂载时(以及可选的卸载时)或 B) 当某些事情发生变化时.

<块引用>

children = [truc"];

这是非常可疑的代码,因为 children 是一个道具.您不应该分配道具(甚至不应该分配它们的解构副本).道具是由父组件控制的状态.组件应该只使用它们,不要试图直接修改它们.

I try to understand how useEffect() work in React, and why is executed in the last not in the order of my code. This issue causes a problem in my bigger program. My question : There is a possibility to choice when this one is executed ?

log of the console, like you see, is not of the order of print :(

0 children null App.js:11:10
2 children null App.js:16:10
1 children 
Array [ "truc" ]

https://codesandbox.io/s/busy-cookies-yvq16?file=/src/App.js

I make this snippet code to explain my problem

import "./styles.css";
import { useEffect } from "react";
let list = [];
function Buffer() {
  let init = null;
  list.push(init);
  return <Comp>{list[0]}</Comp>;
}

function Comp({ children }) {
  console.log("0 children", children);
  useEffect(() => {
    children = ["truc"];
    console.log("1 children", children);
  }, []);
  console.log("2 children", children);
  return <div>Super Buffer</div>;
}

export default function App() {
  return (
    <div className="App">
      <Buffer />
    </div>
  );
}

解决方案

why is executed in the last not in the order of my code.

Because that's its purpose, that's what it's for. From the documentation:

useEffect

useEffect(didUpdate);

Accepts a function that contains imperative, possibly effectful code.

Mutations, subscriptions, timers, logging, and other side effects are not allowed inside the main body of a function component (referred to as React’s render phase). Doing so will lead to confusing bugs and inconsistencies in the UI.

Instead, use useEffect. The function passed to useEffect will run after the render is committed to the screen. Think of effects as an escape hatch from React’s purely functional world into the imperative world.

This article by Dan Abramov may also be useful: A Complete Guide to useEffect. Despite the title, it doesn't just cover useEffect, but the whole way hooks and function components work.

There is a possibility to choice when this one is executed ?

It's not really clear from your question what you want to do instead, but if you want to do something right away, just do it right away without any wrapper function. But remember that your component function runs every time the component needs to re-render, so useEffect is what you use to run things only A) When the component first mounts (and optionally when it unmounts) or B) When certain things change.

children = ["truc"];

That's very suspect code, since children is a prop. You shouldn't be assigning to props (not even destructured copies of them). Props are state controlled by the parent component. The component should only use them, not try to directly modify them.

这篇关于在 React 中执行 useEffect 时如何选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆