Search code examples
reactjsweb-chat

React App: how to pass a variable to other file and read its value there


I am building on sample 16 from Github/Webchat to build a webpage with a webchat interface.

https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/16.customization-selectable-activity

The react app consists off different .js files to build the website( Webchat.js, Instuctor.js, App.js, Index.js) and I can't provide file Inspector.js with the data I gathered in file Webchat.js. I can't find the right code to read the value of a variable from file Webchat.js in file Inspector.js.

I want to build a Webpage where I have on the left side a Chatbot (BotFrameWork) running, and next to it a table running which shows data that has been collected by the chatbot.

I tried answers from

how to get a variable from a file to another file in node.js

but doesn't work. I tried to get the state of Webchat but gives only undefined.

Example: (webchat.js) I fetched data from the bot (like [link]How to create a side window or iframe that shows data that was gathered by a Web-Chat in one web page?) and saved it in a state variable 'test'.

(instructor.js) I want to show that data e.g. in a label that is getting updated when new data comes in. How do I get access now to the value of 'test' that is created in another file?

What doesnt work: in instuctor.js:

var test2 = require ('./webchat'); Console.log(test2.state.test) //this is how I imagine it to work --> undefined with require I only get an object that has a 'name' variable 'Webchat' and which i can get out with: console.log(test2.default.name);


Solution

  • React only supports one-way data binding, so if you want to share a variable between multiple components, you need to elevate the state to the parent and pass the variable and change handlers to the children as props.

    In the example below, Parent has two children: ChildA and ChildB. We could keep myValue in ChildA's state, but then ChildB wouldn't be able to access it, so we elevate myValue to the parent and pass it to both children as props. We also, pass a change handler to ChildB so it can update the value when the user clicks it.

    import React from 'react';
    
    const ChildA = ({ myValue }) => (
      <div>
        {
          myValue 
          ? <h1>Hello World</h1>
          : <h1>Goodbye!</h1>
        }
      </div>
    );
    
    const ChildB = ({ myValue, handleMyValueChange}) => (
      <button onClick={ () => handleMyValueChange(false) } disabled={ myValue }>
        Click Me!
      </button>
    );
    
    class Parent extends React.Component {
    
      constructor(props) {
        super(props);
    
        this.state = { myValue: true }
      }
    
      render() {
        return (
          <div>
            <ChildA myValue={this.props.myValue}/>
            <ChildB myValue={this.props.myValue}  handleMyValueChange={ handleMyValueChange }/>
          </div>
        )
      }
    
      handleMyValueChange = myValue => {
        this.setState({ myValue });
      }
    }
    

    In terms of the sample you referenced, the parent class is App and the two children are ReactWebChat and Inspector. I would recommend elevating the state of your variable to the parent - App - and pass it as a prop to the Inspector class. Then you can add a custom store middleware to ReactWebChat that updates your variable when the bot sends an update event. For more information on how to configure your bot to send update events and how to make Web Chat listen for them, take a look at this StackOverflow Question.

    Hope this helps!