首页 > 解决方案 > 如果 React 组件总是呈现 null,我应该使用它,还是只使用一个函数?

问题描述

我正在制作一个 UI 并遇到了一些让我想知道的东西。我制作了一个通用的可重用函数,它获取数据并在回调中返回它,该回调由调用该函数的任何函数提供给该函数。但这就是它所做的一切,它获取数据并继续传递。目前,该功能最多可以使用约 15 个不同的参数/道具。

一开始我把它做成了一个 React 组件,因为这样调用函数是可行的:

<SomeFunction 
  param1={some_param_1}
  param2={some_param_2}
  ...
/>

这样我可以很容易地随意添加和省略参数。但是,SomeFunction总是返回null,因为它的主要目的是在回调中返回获取的数据。是否应该将此组件恢复为一个没有任何 React 的简单函数?如果是这样,处理参数的最佳方法是什么?

我的脑海里可以很快想出两个选择,第一个是位置论点:

function someFunction(param1, param2, ... param15)

但这似乎有点牵强,因为如果我想将某些东西作为第 15 个参数传递,我需要提供许多空值等。

想到的另一种方法是使用对象:

function someFunction(options)

然后访问参数,如options.param1options.param2


在这种情况下,组件方法还是函数方法更好?在 JS 中处理函数的大量可选参数的最佳方法是什么?我不是一个完全的菜鸟,但感觉在 JS 世界中有很多方法可以处理事物和最佳实践,更不用说语言及其衍生语言不断变化的性质了。

标签: javascriptreactjs

解决方案


两个建议:

  1. 使其成为接受其参数作为对象的普通函数,可能使用解构。(一个组件接收它的道具作为一个对象,所以这基本上是一回事。)

  2. 返回一个承诺,而不是传入一个回调。Promise 提供标准语义,可以awaitasync函数中使用和/或与各种 Promise 组合器(Promise.allPromise.race等)结合使用。

例如,如果您的函数当前使用提供承诺的东西(如fetch):

async function fetchTheInformation({param1, param2, param3 = "default for param3"}) {
    const response = await fetch(/*...*/);
    if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
    }
    return response.appropriateMethodHere(); // .text(), .json(), .arrayBuffer(), etc.
}

如果它不使用提供承诺的东西:

function fetchTheInformation({param1, param2, param3 = "default for param3"}) {
    return new Promise((resolve, reject) => {
        // ...start the operation and call `resolve` if it works, `reject` with an `Error` if it doesn't...
    });
}

在任何一种情况下,对它的调用都可以在async函数中如下所示:

const information = await fetchTheInformation({
    param1: "parameter 1",
    param2, // <=== If you happen to have `param2` in a variable/constant with the same name, no need to repeat it
});

(错误 [rejections] 将自动传播到async要在那里处理的函数的调用者)

或在非async函数中:

fetchTheInformation({
    param1: "parameter 1",
    param2, // <=== If you happen to have `param2` in a variable/constant with the same name, no need to repeat it, this is just like `param2: param,`
})
.then(information => {
    // ...use the information...
})
.catch(error => {          // Or return the promise chain to something else that will handle errors
    // ...handle/report error...
});

关于参数列表:我假设至少需要一个参数,但如果它们都是可选的(具有合理的默认值),您可以这样做:

function example({a = "default for a", b = "default for b", c = "default for c"} = {}) {
}

解构后的表达式=为这些解构参数提供默认值。最后= {}的 使整个参数对象成为可选的,您可以使用上面的example()orexample({})example({a: "something"})等。


推荐阅读