React + Meteor + Bootstrap Modal managing data

302 views Asked by At

I have a Meteor application with React where I have a component called ChatManager. The component imports my chatrooms.js API for publishing my chatrooms collection. It also imports my EditChatRoom component and my ChatRoomRecord component.

Basically here is a summary of the file structure of relevant code:

-imports
  -api
    -chatrooms.js
  -ui
    -chatmanager
      -ChatRoomRecord.jsx
      -EditChatRoom.jsx
    ChatManager.jsx

My ChatRoomRecord component has an onClick function which works successfully at logging the click and the chatroom prop.

My EditChatRoom is a modal where id="editChatRoomModal"

The ChatManager component is the one that holds both the ChatRoomRecord and the EditChatRoom components.

How can I send that chatroom prop that I've registered through to the EditChatRoom component? And on a side note, how could I open the editChatRoomModal using React?

Help is much appreciated! Thanks!

Edit: Added Information

Here is a basic representation of my ChatManager Component:

class ChatManager extends Component {
    renderChatRoomRecords() {
        return this.props.chatrooms.map((chatroom) => (
            <ChatRoomRecord key={chatrooom._id} chatroom={chatroom} />
        ))
    }

    render() {
        return (
            <div>
                <EditChatRoom />
                <table>
                    <tbody>
                        {this.renderChatRoomRecords()}
                    </tbody>
                </table>
            </div>
        )
    }
}

ChatManager.PropTypes = {
    chatrooms: PropTypes.array.isRequired
}

export default createContainer(() => {
    Meteor.subscribe('chatrooms')
    return { chatrooms: ChatRooms.find({}).fetch() }
}, ChatManager)

Then here is my ChatRoomRecord component:

export class ChatRoomRecord extends Component {
    constructor(props) {
        super(props)
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick(event) {
        event.preventDefault()
        console.log("Click registered successfully: " + this.props.chatroom._id)
    }

    render() {
        return (
            <tr onClick{this.handleClick}>
                {/* This code isn't relevant to the problem */}
            </tr>
        )
    }
}

ChatRoomRecord.PropTypes = {
    chatroom: PropTypes.object.isRequired
}

This works greats so there's no problem in the mapping and the click event works where it registers the click and shows the chatroom._id that was clicked.

Here's my EditChatRoom component:

export class EditChatRoom extends Component {
    render() {
        return (
            <div className="modal fade" id="editChatRoomModal" tabIndex="-1" role="dialog">
                {/* This code isn't relevant to the problem */}
            </div>
        )
    }
}

I need to open this modal and pass through the chatroom that was clicked in my ChatRoomRecord component.

Hope this better explains the problem.

1

There are 1 answers

1
kkkkkkk On BEST ANSWER

You could simply use Session to show the selected record and the state of the modal (show or hide):

ChatRoomRecord.jsx

export class ChatRoomRecord extends Component {
    // ...

    handleClick(event) {
        event.preventDefault()
        Session.set('selectedRecordId', this.props.chatroom._id);
        Session.set('isShowModal', true);
    }

    // ...
}

EditChatRoom.jsx

class EditChatRoom extends Component {
  render() {
    const {
      selectedRecordId
    } = this.props;

    return (
      <div className="modal fade" id="editChatRoomModal" tabIndex="-1" role="dialog">
        {/* use the selectedRecordId */}
      </div>
    )
  }
}

export default createContainer(() => {

  // show modal if isShowModal is true
  if (Session.get('isShowModal')) {
    $('#editChatRoomModal').show();
  } else {
    $('#editChatRoomModal').hide();
  }

  return {
    selectedRecordId: Session.get('selectedRecordId'),
  };
}, EditChatRoom)

This code works though it is just for demonstration how to solve your problem. I recommend you use react-bootstrap instead of the normal Bootstrap. And use another reactive source (ReactiveVar or ReactiveDict) to store reactive values instead of Session, because Session has global scope so it is very easy to mess up