FredrikOseberg / react-chatbot-kit

MIT License
297 stars 139 forks source link

How to pass props to my custom Widget #163

Closed jhonatan-dev closed 7 months ago

jhonatan-dev commented 7 months ago

I wanna pass props to custom Widgets. I tried to use setState in ActionProvider. It didn't work. Please let me know if anyone knows how to do that.

tech-alpinist commented 7 months ago

You can pass as payload to customWidgets.

you can do in actionProvider.

import React from 'react';

const ActionProvider = ({ createChatBotMessage, setState, children }) => {
  const handleHello = () => {
    const botMessage = createChatBotMessage('Hello. Nice to meet you.');

    setState((prev) => ({
      ...prev,
      loading: false,
      messages: [...prev.messages, botMessage],
    }));
  };

  const handleDog = () => {
    setState((prev) => ({
      ...prev,
      loading: true,
    }));
    fetch('https://dog.ceo/api/breeds/image/random')
        .then((res) => res.json())
        .then((data) => {
            const botMessage = createChatBotMessage(
            "Here's a nice dog picture for you!",
            {
                widget: 'dogPicture',
                payload: {data.message}
            }
            );

            setState((prev) => ({
                ...prev,
                loading: false,
                messages: [...prev.messages, botMessage],
            }));
        })

  };

  // Put the handleHello and handleDog function in the actions object to pass to the MessageParser
  return (
    <div>
      {React.Children.map(children, (child) => {
        return React.cloneElement(child, {
          actions: {
            handleHello,
            handleDog,
          },
        });
      })}
    </div>
  );
};

export default ActionProvider;
jhonatan-dev commented 7 months ago

You can pass as payload to customWidgets.

you can do in actionProvider.

import React from 'react';

const ActionProvider = ({ createChatBotMessage, setState, children }) => {
  const handleHello = () => {
    const botMessage = createChatBotMessage('Hello. Nice to meet you.');

    setState((prev) => ({
      ...prev,
      loading: false,
      messages: [...prev.messages, botMessage],
    }));
  };

  const handleDog = () => {
    setState((prev) => ({
      ...prev,
      loading: true,
    }));
    fetch('https://dog.ceo/api/breeds/image/random')
        .then((res) => res.json())
        .then((data) => {
            const botMessage = createChatBotMessage(
            "Here's a nice dog picture for you!",
            {
                widget: 'dogPicture',
                payload: {data.message}
            }
            );

            setState((prev) => ({
                ...prev,
                loading: false,
                messages: [...prev.messages, botMessage],
            }));
        })

  };

  // Put the handleHello and handleDog function in the actions object to pass to the MessageParser
  return (
    <div>
      {React.Children.map(children, (child) => {
        return React.cloneElement(child, {
          actions: {
            handleHello,
            handleDog,
          },
        });
      })}
    </div>
  );
};

export default ActionProvider;

how to get the payload in custom Widget?

tech-alpinist commented 7 months ago

Here is how to reference the payload in custom widgets

// new file called DogPicture.jsx
import React, { useEffect, useState } from 'react';

const DogPicture = (props) => {
  const [imageUrl, setImageUrl] = useState('');

  useEffect(() => {
    setImageUrl(props.payload)
  }, [props.payload]);

  return (
    <div>
      <img src={imageUrl} alt='a dog' />
    </div>
  );
};

export default DogPicture;