功能组件中的React Native const vs let vs var



这是一个更广泛的问题,涉及在react原生函数组件(与类组件相反)中使用不同的变量声明,特别是let与const的使用,以及它们如何受到渲染等的影响。对于这个问题,当我说"render"或"re-render"时,我指的是render函数的执行(如下面的"MyFunctionalComponent"),而不一定是UI更新/更改。

根据我的理解,与普通的js不同,const变量在react/areact native中并不完全是"常量",并且可以这样更改(使用钩子?):

export default function MyFunctionalComponent() {
const [test, setTest] = useState(false);
const testFunction = () => { //some sort of function, maybe called by a button press
setTest(true); //this can change test, but something like 'test = true' throws an error
}
}

然而,根据我的理解,我们可以采取类似的行为:

export default function MyFunctionalComponent() {

let test = false
const testFunction = () => { //some sort of function, maybe called by a button press
test = true;
}
}

然而,我看过的大多数react原生示例和教程似乎总是使用const语法,尽管它似乎涉及更多的代码。为什么?个人偏好,还是必要性?const方法是否以某种方式重新呈现/重新调用带有const变量新值的MyFunctionalComponent?

接下来,我不确定导致这种情况的确切行为,但有时在函数组件内部使用const语法时,变量会在渲染调用之间更改和保存状态,有时,每次调用渲染时,const变量都会重置为默认状态。(我知道这部分很模糊,所以如果没有足够的细节,可以忽略它)为什么会发生这种情况?

类似地,当const是在函数组件之外而不是在…内创建时,我看到了不同的行为。。。scope是否如您所期望的那样工作?它们(仍然?)在新的渲染调用中被重新实例化了吗?"setState"是否调用重新呈现?缩短前面的问题,为什么我的一些const在重新渲染时保留它们的状态,而有些似乎重置为默认值?

var在哪里?它的行为与常规js中的相同吗?还是也受到react的影响?(我觉得我已经掌握了正则js中这些变量声明的差异,但这种带有react的const行为让我对这一切产生了疑问)。

因此,总的来说,问题基本上是,let、var和const有什么区别/优势,特别是在react/areact native中,以及它们与常规javascript有何不同?

最后,在react native中,类组件和功能组件之间有区别吗?

谢谢你阅读这个长问题。

个人偏好,还是必需品?

仅限首选项和样式。

使用const来声明有状态变量,而不是varlet可以使代码的意图更加清晰。这是不必要的——如果你看到的所有组件都使用varlet,它们几乎都能正常工作——但这会给阅读代码的人带来轻微的困惑。

React是用JavaScript编写的。React中用const声明的有状态变量不能像在普通JavaScript中一样重新分配。缺少的关键是,每次重新渲染时,都会再次调用组件函数,从而导致useState函数的调用返回不同的值。

关于如何在带有const的vanillaJS中工作并多次调用函数的快速示例:

let i = 0;
const getI = () => i;
const fn = () => {
const theValue = getI();
console.log(theValue);
i++;
setTimeout(fn, 1000);
};
fn();

这并不是说变量被重新分配(由于使用const,这将被禁止),而是整个函数再次运行,导致在新初始化时为用const声明的变量分配了一个新值。

接下来,我不确定导致这种情况的确切行为,但有时在函数组件内部使用const语法时,变量会在渲染调用之间更改和保存状态,有时,每次调用渲染时,const变量都会重置为默认状态。(我知道这部分很模糊,所以如果没有足够的细节,可以忽略它)为什么会发生这种情况?

您可能指的是过时的闭包问题。如果导致差异的变量绑定来自以前的渲染,而不是当前渲染,则可能会发生这种情况。

为了在vanillaJS中获得一个快速的例子,根据上面的片段改编,我将在第一个渲染上添加一个超时,这将导致只使用第一个渲染的i

let i = 0;
const getI = () => i;
const fn = () => {
const theValue = getI();
console.log(theValue);
if (theValue === 0) {
// first render
setTimeout(() => {
console.log('Timeout from first render running, sees a theValue of:', theValue);
}, 5000);
}
i++;
setTimeout(fn, 1000);
};
fn();

类似地,当const在函数组件之外而不是在函数组件内部创建时,我看到了不同的行为。。。scope是否如您所期望的那样工作?它们(仍然?)在新的渲染调用中被重新实例化了吗?

取决于变量在哪个块中。如果它在另一个组件中,它可能会被重新初始化。如果它不在另一个组件中,那么它可能不在。例如,通常有一个模块导出一个组件,该组件具有一些绝对不变的const值,所有组件都使用这些值,例如

const apiKey = 'someApiKey';
export const ApiInterface = () => {
// ...
};

具体来说,关于constletvarletvar的问题是它们允许重新分配,但在React中更改有状态变量的唯一正确方法是调用状态设置器,而不是重新分配变量。调用状态设置器将导致重新渲染;重新指定变量不会导致重新渲染,重新指定变量会导致指定的值在下一次重新渲染时丢失。因此,非常清楚有状态变量不应该被重新分配是一个好主意。

最后,在react native中,类组件和功能组件之间有区别吗?

是的,在类组件中,state作为实例(this)的属性。状态不再是一个独立的const标识符,而是一个更大对象的属性,因此类组件中的有状态值没有constletvar,除非您从状态中提取值并自己将其放入正常的独立变量中,在这种情况下,它们的行为与任何其他独立变量一样。

最新更新