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

如果道具被改变了,我可以用什么方法给出初始值,以避免反模式效果

厍彭薄
2023-03-14

我使用反应钩。如果道具被改变了,有什么方法可以获得初始值?我想避免反模式效应。

场景1:在构建DOM之前。

据我所知,就这些目的而言,这是一份备忘录。如果有其他选项,您可以选择显示它们。

情景2:在DOM之后

在这个变体中,useLayoutEffect,useEffect。如果有其他选项,您可以选择显示它们。

import React, { useState, useMemo, useLayoutEffect, useEffect } from "react";
import ReactDOM from "react-dom";

import "./styles.css";
const X = () => {
  const [x, setX] = useState(0);
  return (
    <div>
      <div>
        <Y x={x} />
      </div>
      <div onClick={() => setX(x + 1)}>{"go"}</div>
    </div>
  );
};

function Y({ x }) {
  const [y, setY] = useState(x);

  /*useMemo(() => {
    console.log("");
    setY(x);
  }, [x]);*/
  /*useEffect(() => {
    console.log("");
    setY(x);
  }, [x]);*/
  /*useLayoutEffect(() => {
    console.log("");
    setY(x);
  }, [x]);*/
  console.log(y);
  return <div className="App">{console.log(y, "DOM")}</div>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<X />, rootElement);

我认为使用所有这些挂钩不是一个好的做法。但我看不到其他解决办法。也许还有第三种不使用挂钩的选择?

共有2个答案

鲁建茗
2023-03-14

“获取初始值”是什么意思?如果只想存储传递给该组件的第一个值,可以使用useRef()

function Y ({ x }) {
  const initial = useRef(x)
  const y = initial.current

  return <div>the inital value was {y} and the current value is {x}</div>
}

如果你想得到以前的值,你可以这样做:

function Y ({ x }) {
  const previous = useRef(null)

  const y = previous.current
  // A component coud rerender all the time
  // so only change the previous value when x changes
  useEffect(() => { previous.current = x }, [x])

  return <div>the previous value was {y} and the current value is {x}</div>
}
祁建业
2023-03-14

在您的示例中,是否需要将状态存储在Y中?为什么不直接参考道具x

当道具x更改时,如果您希望更新y中的y状态,则可以使用依赖于xuseffect

useEffect(() => {
  setY(x);
}, [x]);

在这种情况下,您不会使用usemo,因为您没有计算并返回值。

 类似资料:
  • 升级到Vue 2.0我有很常见的问题 我得到警告: 避免直接改变道具,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于道具值的数据或计算属性。正在变异的道具:“用户名”(在组件中找到) 我读了很多次文档,但仍然不明白如何修复它。 和在主Vue应用中声明。 这是我的代码: 我尝试了,但它似乎不起作用,我不明白为什么。它应该将该值绑定到父级(主Vue应用程序)

  • 问题内容: 我了解到try catch语句的finally子句始终执行。但是有人对我说,有可能避免执行它(删除它不是一种选择)。 -有人怎么可能? -我也很好奇知道为什么有人要避免执行它? 问题答案: 使用该块中未捕获的异常将其杀死,或者将整个JVM杀死(这将杀死线程)。 除了不良的设计外,没有充分的理由停止执行块。如果不应该每次都运行它,则不要将其放在一个块中。 使用下面的测试代码,我运行了两种

  • 问题内容: TensorFlow中初始化变量的标准方法是 经过一段时间的学习后,我创建了一组新变量,但是一旦初始化它们,它将重置所有现有变量。目前,解决此问题的方法是保存所需的所有变量,然后在tf.initalize_all_variables调用之后重新应用它们。这有效,但是有点笨拙。我在文档中找不到像这样的东西… 有谁知道初始化未初始化变量的好方法吗? 问题答案: 没有优雅的方法可以枚举图中的

  • 我是Vue JS的新手,我遇到了这个问题,我试图通过将父道具传递给孩子来制作数据表 我犯了这个错误 [Vue warn]:避免直接改变道具,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于道具值的数据或计算属性。道具正在变异:“editem” 这是我的密码 这是我的页面: 这是我的组件:

  • 问题内容: 除了使用关键字调用构造函数时,Java语言中的语句可以返回值的确切情况是什么? 例: 如果我没记错的话,如果它是一个非函数原语,将被返回。否则返回。这个对吗? 换句话说,什么值可以引起? 问题答案: 确切的条件在内部属性上进行了描述,该属性由操作员使用: 来自ECMA-262第3条。版本规格: 13.2.2 调用对象的属性时,将执行以下步骤: 创建一个新的本机ECMAScript对象。

  • 问题内容: 通过查看的代码类,我才知道,当我们正在使用的方法或者它不是创建一个新的对象,但它返回同一个对象的引用,并覆盖其可以修改方法[ ,,,。 ..] 因此,我运行了此测试: 结果是。 现在的重点是为什么它指的是同一对象?为什么不创建新对象? 问题答案: (问题的答案在底部) 创建不可修改的列表时,其目的是不应 由您以外的其他人 (即API的客户端)对其进行修改。 该方法将创建一个新类型的对象