How to using React in NodeRed

Hi all,
I have a tiny project with "react" implemented and now I want to migrate to NodeRed. But I dont know, how can I do this

hier is index.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Comments</title>


<script src="../Libraries/es6/es6-promise.min.js"></script>
<script src="../Libraries/es6/es6-promise.auto.min.js"></script> 
    <!-- React and a Babel to transpile JSX on client side-->
    <script src="../Libraries/react/react.production.min.js"></script>
    <script src="../Libraries/react/react-dom.production.min.js"></script>
    <script src="../Libraries/babel/babel.min.js" data-presets="es2015,react,stage1"></script>

	<!-- timeago.js for display of ".. ago" times -->
	 <script src="../Libraries/timeago/timeago.min.js"></script>
	 
    <!-- Semantic UI -->
    <script src="../Libraries/semantic-ui/semantic-ui-react.min.js"></script>
    <link rel="stylesheet" href="../Libraries/semantic-ui/semantic.min.css">

	<!-- The config file -->
	<script type="text/javascript" src="config/config.js"></script>
	
    <!-- our application files -->
    <script type="text/babel" src="src/comments.js"></script>
    <script type="text/babel" src="src/main.js">
    
    </script>
</head>

<body>
   
    <div id="root"></div>

</body>

</html>

main.js

const { Segment } = semanticUIReact

const App = () => (
  <div>
    <CommentsSection/>
  </div>
)
ReactDOM.render(<App />, document.getElementById('root'))

comment.js

const {
  Comment,
  Input,
  Button,
  Divider,
  Icon,
  TextArea,
  Form,
  Loader,
  Segment
} = semanticUIReact;



//Version of this module
const module_version = 1;



class CommentsSection extends React.Component {
  constructor(props) {
    super(props);
    this.handleOnInput = this.handleOnInput.bind(this);
    this.handleAddComment = this.handleAddComment.bind(this);
    this.getUserName = this.getUserName.bind(this);
    this.getUserAvatar = this.getUserAvatar.bind(this);
    this.handleDelete = this.handleDelete.bind(this);
	this.handleShowAll = this.handleShowAll.bind(this);
	
	var userData ;

	
	
    this.state = {
      docID: null,
      userID: 0,
	  number_to_show: number_of_displayed_comments,
      textAreaValue: "",
      comments: {
        total: 0,
        version: module_version,
        commentshistory: []
      }
    };
  }

  componentDidMount() {
    //get userID from db hier
	 
  }
 
 componentDidUpdate(){
 postContentSize();
 }

  handleAddComment(e) {
  // start by reading again comments from database, in case another user made an update since the last read.
    
  }

  handleOnInput(e, { value }) {
    this.setState({
      textAreaValue: value
    });
  }
  handleShowAll(e, { value }) {
 
    this.setState({
      number_to_show: this.state.total,
    }
	);
  }
  
  
  
  handleDelete(key) {
    // some code hier
   
  }

 
  getUserAvatar(userID) {
    if (userID == 10000) {
      return "https://react.semantic-ui.com/assets/images/avatar/small/matt.jpg";
    }
    if (userID == 10002) {
      return "https://react.semantic-ui.com/assets/images/avatar/small/jenny.jpg";
    }
    //fallback: default image
    return "./images/default_avatar.png";
  }

  render() {
  
    return (
      <Segment basic secondary>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "flex-end"
          }}
        >
          <div style={{ flex: "1" }}>
            <Form reply>
              <Form.TextArea
                autoHeight
                rows={1}
                placeholder="Write your comment here..."
                onInput={this.handleOnInput}
                value={this.state.textAreaValue}
                id="textArea"
              />
            </Form>
          </div>

          <div style={{ flex: "0", marginLeft: "10px" }}>
            <Button
              onClick={this.handleAddComment}
              disabled={this.state.textAreaValue.length > 0 ? false : true}
              content="Add"
              primary
            />
		
          </div>
        </div>
        <Comment.Group>
          {this.state.comments.total == 0 ? (
            <div />
          ) : (
		  
		  
            this.state.comments.commentshistory.slice(0, this.state.number_to_show).map((item, key) => (
              <Comment>
                <Comment.Avatar src={this.getUserAvatar(item.user)} />
                <Comment.Content>
                  <Comment.Author as="a">
                    {item.user == this.state.userID
                      ? "You"
                      : (item.user)}
                  </Comment.Author>
                  <Comment.Metadata>
                    <span title={Date(item.timestamp)}>
                      {timeago().format(item.timestamp)}
                    </span>
                  </Comment.Metadata>
                  <Comment.Text>
                    {/*This function manages the line breaks in the JSON. Compatible with IE11*/}
                    {item.text.split(/\n/).map(function(item, key) {
                      return (
                        <span key={key}>
                          {item}
                          <br />
                        </span>
                      );
                    })}
                  </Comment.Text>
                  <Comment.Actions>
                    <Comment.Action
                      onClick={(e, value) => {
                        this.handleDelete(key);
                      }}
                      style={{
                        display: item.user == this.state.userID ? "" : "none"
                      }}
                    >
                      Delete
                    </Comment.Action>
                  </Comment.Actions>
                </Comment.Content>
              </Comment>
            ))
          )}
        </Comment.Group>
		
		 {this.state.comments.total > this.state.number_to_show ? (
           <Divider horizontal clearing>
		<Button onClick={this.handleShowAll}>
		Show {this.state.comments.total - this.state.number_to_show} older
		</Button>
		</Divider>

          ) : (
		  
		  <div/>
		  )
		  }

		
      </Segment>
    );
  }
}

function postContentSize() {
     const contentSize: WpLib.Notify.View.ContentSizeData = {
          width: document.getElementById("root").scrollWidth,
          height: document.getElementById("root").scrollHeight
		 
     }
     plugin.postNotify(WpLib.Notify.View.Module, WpLib.Notify.View.ContentSize, contentSize)
}


You can use REACT with uibuilder.

uibuilder provides the framework for you and you include the uibuilderfe.js file in your front-end code. That gives you easy access to messaging between your front-end app and Node-RED.

uibuilder will also make other front-end libraries easily available for you and even lets you edit your front-end code from within the Node-RED editor if you want.

Doesn't yet provide an interface for doing build steps though that is on the roadmap. You can still do them though, you just have to know the folder structure which is given in the docs.

Next release (v3) is being worked on and that will include (all being well) a new security function based on JWT, websockets with options for inserting your own functions to do things like user authentication.

uibuilder comes with VueJS, bootstrap-vue as default but you can ignore those and add REACT if that is your preference. There is a basic example in the WIKI.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.