欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

用React實(shí)現(xiàn)一個(gè)類(lèi) chatGPT 的交互式問(wèn)答組件的方法詳解

 更新時(shí)間:2023年06月29日 09:47:15   作者:hahayq  
這篇文章主要給大家詳細(xì)介紹如何用React實(shí)現(xiàn)一個(gè)類(lèi) chatGPT 的交互式問(wèn)答組件的方法,文中有詳細(xì)的代碼示例,對(duì)我們學(xué)習(xí)有一定的幫助,需要的朋友可以參考下

API文檔

屬性名描述類(lèi)型默認(rèn)值
recommendList推薦模板列表string[] | undefinednull
commonUseList常用模板列表string[] | undefinednull
uploadProps文件上傳,同 antd Upload 組件{ accept?: string; children?: ReactNode; maxCount?: number; multiple?: boolean; } | undefinednull
autoCompleteProps輸入框自動(dòng)補(bǔ)全,同 antd AutoComplete 組件{ options?: DefaultOptionType[]; onSearch?: ((value: string) => void); } | undefinednull
onSend發(fā)送消息((msg: IQuestion) => void) | undefinednull
onMsgLike點(diǎn)贊回答((msg: IQuestion) => void) | undefinednull
onMsgNotLike點(diǎn)踩回答((msg: IQuestion) => void) | undefinednull
onRefresh刷新回答((msg: IQuestion) => void) | undefinednull
renderAvatar自定義頭像((msg: IMessage) => ReactNode) | undefinednull
renderTools自定義消息框底部操作欄((msg: IMessage) => ReactNode) | undefinednull
isAnimation是否開(kāi)啟消息動(dòng)畫(huà)效果boolean | undefinednull
className自定義類(lèi)名boolean | undefinednull
style自定義樣式CSSProperties | undefinednull
loading加載狀態(tài)boolean | undefinednull
messages消息列表IMessage[] | undefinednull
# 功能介紹
這個(gè)組件的主要功能主要包括:
  • 輸入框上傳附件
  • 輸入框自動(dòng)補(bǔ)全
  • 自定義消息操作欄
  • 自定義頭像
  • 模板調(diào)用

下面會(huì)挨個(gè)介紹功能

輸入框上傳文件

這個(gè)功能很簡(jiǎn)單就是支持輸入框上傳附件,然后會(huì)把附件和問(wèn)題一起丟給使用者,由使用者自己去調(diào)用api接口來(lái)獲取回答.上傳組件采用的是antd的Upload組件,API也一致.大致代碼如下:

import React from 'react';
import { Chat, useMessage, EMessageType } from './chat';
export default function () {
  const { msgProps } = useMessage(
    (question, lastAnswer) => {
      return new Promise((resolve, reject) => {
        const { content, fileList } = question;
        setTimeout(() => {
          resolve({
            content:
              '\n\n' +
              (lastAnswer ? '## 我又想了一下 \n\n' : '') +
              content?.replace(/嗎/g, '呢').replace(/你/g, '我') +
              '\n\n' +
              fileList.map((item) => item.name).join(' ') +
              '\n\n![lena](https://img1.baidu.com/it/u=2041864569,220923158&fm=253&fmt=auto&app=138&f=JPEG?w=300&h=284)'
          });
        }, 2000);
      });
    },
    {
      uploadProps: {
        multiple: true
      },
      defaultMsgs: [
        {
          key: 1,
          type: EMessageType.AI,
          content: '快來(lái)和我對(duì)話吧',
          renderTools: () => null,
          isAnimation: false
        }
      ]
    }
  );
  return (
      <Chat {...msgProps} />
  );
}

輸入框自動(dòng)補(bǔ)全

自動(dòng)補(bǔ)全采用的是antd的Autocomplete組件,API也一致,原理就是當(dāng)輸入框內(nèi)容改變時(shí)去請(qǐng)求關(guān)聯(lián)內(nèi)容然后改變Autocomplete的options,就能實(shí)現(xiàn)自動(dòng)補(bǔ)全啦.

import React, { useState } from 'react';
import { Chat, useMessage, EMessageType, IMessage } from './chat';
export default function () {
  const [options, setOptions] = useState<{ value: string }[]>([]);
  const handleSearch = (value: string) => {
    setOptions(!value ? [] : [{ value }, { value: value + value }, { value: value + value + value }]);
  };
  const { msgProps } = useMessage(
    (question, lastAnswer) => {
      return new Promise((resolve, reject) => {
        const { content } = question;
        setTimeout(() => {
          resolve({
            isAnimation: !!lastAnswer,
            content:
              '\n\n' +
              (lastAnswer ? '## 我又想了一下 \n\n' : '') +
              content?.replace(/嗎/g, '呢').replace(/你/g, '我') +
              '\n\n![lena](https://img1.baidu.com/it/u=2041864569,220923158&fm=253&fmt=auto&app=138&f=JPEG?w=300&h=284)'
          });
        }, 2000);
      });
    },
    {
      autoCompleteProps: {
        options,
        onSearch: handleSearch
      }
    }
  );
  return (
      <Chat {...msgProps} />
  );
}

自定義消息操作欄

由于每條消息下方還有操作欄,默認(rèn)的有重新回答、點(diǎn)贊、點(diǎn)踩、復(fù)制等,所以提供了自定義的功能,如果不需要默認(rèn)的這些功能也可以關(guān)閉或者自定義.

import React from 'react';
import { Chat, useMessage, EMessageType, IMessage } from './chat';
export default function () {
  const { msgProps } = useMessage(
    (question, lastAnswer) => {
      return new Promise((resolve, reject) => {
        const { content } = question;
        setTimeout(() => {
          resolve({
            content:
              '\n\n' +
              (lastAnswer ? '## 我又想了一下 \n\n' : '') +
              content?.replace(/嗎/g, '呢').replace(/你/g, '我') +
              '\n\n![lena](https://img1.baidu.com/it/u=2041864569,220923158&fm=253&fmt=auto&app=138&f=JPEG?w=300&h=284)',
            renderTools: (msg: IMessage) => <div>點(diǎn)個(gè)贊吧</div>
          });
        }, 2000);
      });
    },
    {
      renderTools: (msg: IMessage) => <div>這里是自定義操作欄</div>,
      defaultMsgs: [
        {
          key: 1,
          type: EMessageType.AI,
          content: '快來(lái)和我對(duì)話吧',
          renderTools: () => null,
          isAnimation: false
        },
        {
          key: 2,
          type: EMessageType.AI,
          content: '支持每條消息獨(dú)立設(shè)置操作欄',
          renderTools: (msg: IMessage) => <div>這里是消息獨(dú)立操作欄</div>,
          isAnimation: false
        }
      ]
    }
  );
  return (
    <BixiProvider locale={enUS}>
      <Chat {...msgProps} />
    </BixiProvider>
  );
}

自定義頭像

既然是對(duì)話,那肯定得提供自定義頭像的功能啦,使用方式的話是傳入renderAvatar這個(gè)方法,通過(guò)傳入的消息類(lèi)型來(lái)判斷顯示那個(gè)頭像,效果如下

import React from 'react';
import { Chat, useMessage, EMessageType, IMessage } from './chat';
export default function () {
  const { msgProps } = useMessage(
    (question, lastAnswer) => {
      return new Promise((resolve, reject) => {
        const { content } = question;
        setTimeout(() => {
          resolve({
            content:
              '\n\n' +
              (lastAnswer ? '## 我又想了一下 \n\n' : '') +
              content?.replace(/嗎/g, '呢').replace(/你/g, '我')
          });
        }, 2000);
      });
    },
    {
      renderAvatar: (msg: IMessage) => <>{msg.type === EMessageType.AI ? '人工智障' : '大帥比'}</>,
      defaultMsgs: [
        {
          key: 1,
          type: EMessageType.AI,
          content: '快來(lái)和我對(duì)話吧',
          renderTools: () => null,
          isAnimation: false
        },
        {
          key: 2,
          type: EMessageType.Self,
          content: '你真的是人工智能嗎',
          isAnimation: false
        },
        {
          key: 3,
          type: EMessageType.AI,
          content: '支持每條消息單獨(dú)設(shè)置頭像',
          isAnimation: false
        }
      ]
    }
  );
  return (
      <Chat {...msgProps} />
  );
}

模板調(diào)用

這個(gè)功能是比賽要求的,需要給用戶提供一些模板,用戶點(diǎn)擊模板就可以快速搜索答案之類(lèi)的,在輸入框輸入“/”就可以喚醒模板了,實(shí)現(xiàn)方式也很簡(jiǎn)單,監(jiān)聽(tīng)輸入框值的改變,如果輸入值和“/”匹配就直接喚起模板就可以了.效果如下

import React from 'react';
import { Chat, useMessage, EMessageType, IMessage } from './chat';
export default function () {
  const { msgProps } = useMessage(
    (question, lastAnswer) => {
      return new Promise((resolve, reject) => {
        const { content } = question;
        setTimeout(() => {
          resolve({
            content:
              '\n\n' +
              (lastAnswer ? '## 我又想了一下 \n\n' : '') +
              content?.replace(/嗎/g, '呢').replace(/你/g, '我')
          });
        }, 2000);
      });
    },
    {
      recommendList: ['標(biāo)題生成', '文章續(xù)寫(xiě)', '文章潤(rùn)色', '文章大綱', '朋友圈文案', '活動(dòng)方案', '翻譯', '演講稿'],
      commonUseList: ['標(biāo)題生成', '朋友圈文案'],
    }
  );
  return (
      <Chat {...msgProps} />
  );
}

自定義hook

除了上面的功能外,還對(duì)邏輯進(jìn)行了封裝,調(diào)用這個(gè)hook可以獲取到messages、onRefresh、onSend、loading這幾個(gè)主要的props,其他的props你也可以自己傳入. 這個(gè)自定義hook封裝了消息發(fā)送方法,消息刷新方法,組件loading狀態(tài),消息列表等主要邏輯.重新回答的原理是去消息列表中尋找之前最近的一條問(wèn)題,然后在此調(diào)用獲取回答的接口 代碼如下:

import { useState, useCallback } from 'react';
import { IMessage, IChatProps, EMessageType, IQuestion } from './model';
import { uniqueId } from 'lodash-es';
type IUseMessageOption = Omit<IChatProps, 'onSend' | 'onRefresh' | 'loading' | 'messages'> & {
  defaultMsgs: IMessage[];
};
type IService = (msg: IQuestion, lastAnswer?: IMessage) => Promise<IMessage>;
export function useMessage(
  getMsg: IService,
  { defaultMsgs, ...props }: IUseMessageOption
): {
  msgProps: IChatProps;
} {
  const [messageList, setMessageList] = useState<IMessage[]>(defaultMsgs || []);
  const [loading, setLoading] = useState(false);
  const onRefresh = useCallback(
    (item: IMessage) => {
      const index = messageList.findIndex((msg) => msg.key === item.key);
      if (index < 1) return;
      const lastQuestion = messageList
        .slice(0, index)
        .reverse()
        .find((msg) => msg.type === EMessageType.Self);
      if (!lastQuestion) return;
      setLoading(true);
      getMsg(lastQuestion, messageList[index]).then((res) => {
        setLoading(false);
        const key = `${EMessageType.AI}-${uniqueId()}`;
        messageList[index] = { ...res, key, type: EMessageType.AI };
        setMessageList([...messageList]);
      });
    },
    [getMsg, messageList]
  );
  const onSend = useCallback(
    (msg: IQuestion) => {
      setLoading(true);
      setMessageList((list) => list.concat({ ...msg, key: `${EMessageType.Self}-${uniqueId()}`, type: EMessageType.Self }));
      getMsg(msg).then((res) => {
        setLoading(false);
        const key = `${EMessageType.AI}-${uniqueId()}`;
        setMessageList((list) => list.concat({ ...res, key, type: EMessageType.AI }));
      });
    },
    [getMsg]
  );
  return {
    msgProps: {
      messages: messageList,
      onRefresh,
      onSend,
      loading,
      ...props
    }
  };
}

使用方法

該組件使用起來(lái)很簡(jiǎn)單,調(diào)用useMessage這個(gè)hook,傳入api接口(需要返回promise)就可以了,至于其他的組件api也可以一并傳入,還支持傳入歷史消息列表.然后這個(gè)hook就會(huì)返回所有該組件所需要的props,包括消息發(fā)送方法,消息刷新方法,組件loading狀態(tài),消息列表等.是不是很方便呢,哈哈.

以上就是用React實(shí)現(xiàn)一個(gè)類(lèi) chatGPT 的交互式問(wèn)答組件的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于React chatGPT問(wèn)答組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React使用Redux Toolkit的方法示例

    React使用Redux Toolkit的方法示例

    Redux Toolkit可以幫助開(kāi)發(fā)者更快速、更高效地編寫(xiě)Redux應(yīng)用,本文主要介紹了React使用Redux Toolkit的方法示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • React Native自定義Android的SSL證書(shū)鏈校驗(yàn)

    React Native自定義Android的SSL證書(shū)鏈校驗(yàn)

    這篇文章主要為大家介紹了React Native自定義Android的SSL證書(shū)鏈校驗(yàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 需要避免的五個(gè)react的ref錯(cuò)誤用法

    需要避免的五個(gè)react的ref錯(cuò)誤用法

    react是一個(gè)優(yōu)秀的框架,提供了我們很多的便利,但是在使用的過(guò)程中,我們也會(huì)遇到很多的問(wèn)題,其中一個(gè)就是ref的使用,以下是我列出的5個(gè)使用ref的錯(cuò)誤用法,并提供了正確的用法,需要的朋友可以參考下
    2024-12-12
  • 記一個(gè)React.memo引起的bug

    記一個(gè)React.memo引起的bug

    memo可以自己決定是否更新,但它是一個(gè)函數(shù)組件而非一個(gè)類(lèi),本文主要介紹了React.memo引起的bug,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-03-03
  • 詳解如何在Remix 中使用 tailwindcss

    詳解如何在Remix 中使用 tailwindcss

    這篇文章主要為大家介紹了如何在Remix中使用tailwindcss方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • React hooks的優(yōu)缺點(diǎn)詳解

    React hooks的優(yōu)缺點(diǎn)詳解

    這篇文章主要介紹了React hooks的優(yōu)缺點(diǎn)詳解,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • React實(shí)現(xiàn)導(dǎo)出excel文件的操作步驟

    React實(shí)現(xiàn)導(dǎo)出excel文件的操作步驟

    在React項(xiàng)目的TypeScript文件中,因?yàn)樵腏avaScript或TypeScript并沒(méi)有提供直接的Excel導(dǎo)出功能,常用的Excel導(dǎo)出方法通常涉及使用第三方庫(kù),本文介紹了React實(shí)現(xiàn)導(dǎo)出excel文件的操作步驟,需要的朋友可以參考下
    2024-12-12
  • react結(jié)合typescript?封裝組件實(shí)例詳解

    react結(jié)合typescript?封裝組件實(shí)例詳解

    這篇文章主要為大家介紹了react結(jié)合typescript?封裝組件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • React中refs的一些常見(jiàn)用法匯總

    React中refs的一些常見(jiàn)用法匯總

    Refs是一個(gè) 獲取 DOM節(jié)點(diǎn)或React元素實(shí)例的工具,在React中Refs 提供了一種方式,允許用戶訪問(wèn)DOM 節(jié)點(diǎn)或者在render方法中創(chuàng)建的React元素,這篇文章主要給大家介紹了關(guān)于React中refs的一些常見(jiàn)用法,需要的朋友可以參考下
    2021-07-07
  • React實(shí)現(xiàn)原生APP切換效果

    React實(shí)現(xiàn)原生APP切換效果

    最近需要使用 Hybrid 的方式開(kāi)發(fā)一 個(gè) APP,交互和原生 APP 相似并且需要 IM 通信,本文給大家介紹了使用React實(shí)現(xiàn)原生APP切換效果,文中通過(guò)代碼示例講解的非常詳細(xì),感興趣的小伙伴跟著小編一起來(lái)看看吧
    2025-01-01

最新評(píng)論