如何使用反应钩子用一组键多次替换数据?

How do you replace data multiple times with an array of keys using a react hook?

我不确定我的问题措辞是否正确。这是我的问题。我正在尝试使用 Microsoft 的 Cognitive Services Translator 动态翻译我的网页。我和翻译器做了一个反应钩子。如果我只需要翻译一个对象中的一个值,这很好用。

const useAzureTranslate = (data: any, lang: string, objKey: string) => {

    const [translatedData, setTranslatedData] = useState<any | null>([]);

    useEffect(() => {
        Promise.all(data.map(function (obj: any) {
            return axios({
                baseURL: endpoint,
                url: '/translate',
                method: 'post',
                headers: {
                    'Ocp-Apim-Subscription-Key': subscriptionKey,
                    'Ocp-Apim-Subscription-Region': location,
                    'Content-type': 'application/json',
                    'X-ClientTraceId': uuidv4().toString()
                },
                params: {
                    'api-version': '3.0',
                    'from': 'en',
                    'to': lang
                },
                data: [{ "text": obj[objKey] }],
                responseType: 'json'
            }).then(response => {
                // console.log(response.data)
                let translatedText = response.data[0].translations[0].text;
                return { ...obj, [objKey]: translatedText };
            }).catch((error) => {
                console.log(error.response.data.error);
                throw error;
            });
        })).then(newDataArray => {
            // console.log(newDataArray);
            setTranslatedData(newDataArray);
        }).catch(err => {
            console.log(err);
            throw err;
        });
        console.log(translatedData);

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [lang])

    return { translatedData };
}

我希望能够拥有一组键,而不必只翻译一个键值。我不知道该怎么做。

"/translate" API 最多可以翻译 100 个术语。

Translate Request Body

Request body

The body of the request is a JSON array. Each array element is a JSON object with a string property named Text, which represents the string to translate.

[
    {"Text":"I would really like to drive your car around the block a few times."}
]

The following limitations apply:

  • The array can have at most 100 elements.
  • The entire text included in the request cannot exceed 10,000 characters including spaces.

如果您的代码保持在这些限制范围内,那么我建议如下:

  1. 更改 objKey 声明为字符串数组
  2. objKey 数组映射到具有 text 键的对象数组
  3. 将翻译数组合并到映射的 obj 对象的副本中

示例:

const useAzureTranslate = (data: any, lang: string, objKey: string[]) => {
  const [translatedData, setTranslatedData] = useState<any | null>([]);

  useEffect(() => {
    Promise.all(
      data.map(function (obj: any) {
        return axios({
          baseURL: endpoint,
          url: "/translate",
          method: "post",
          headers: {
            "Ocp-Apim-Subscription-Key": subscriptionKey,
            "Ocp-Apim-Subscription-Region": location,
            "Content-type": "application/json",
            "X-ClientTraceId": uuidv4().toString()
          },
          params: {
            "api-version": "3.0",
            from: "en",
            to: lang
          },
          data: objKey.map((key) => ({ text: obj[key] })), // <-- array of "text" objects
          responseType: "json"
        })
          .then((response) => {
            // Reduce array of translations back into current `obj` copy
            return response.data[0].translations.reduce(
              (newObj, { text }, index) => ({
                ...newObj,
                [objKey[index]]: text
              }),
              { ...obj }
            );
          })
          .catch((error) => {
            console.log(error.response.data.error);
            throw error;
          });
      })
    )
      .then((newDataArray) => {
        setTranslatedData(newDataArray);
      })
      .catch((err) => {
        console.log(err);
        throw err;
      });

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [lang]);

  return { translatedData };
};

如果您的代码超出了限制范围,那么您需要先将数据 and/or 关键翻译术语分块,然后按上述方式提出请求。