使用按钮打开对话框以获取一些用户输入

时间:2018-01-05 16:00:16

标签: javascript reactjs firebase material-design

我使用React和firebase创建简化的松弛并使用MDl作为样式。我试图集成一个按钮,打开一个对话框来获取一些用户输入,在这种情况下是新聊天室的名称,然后在提交时它会将数据发送到firebase并将其存储在房间中数组并在列表中显示新的房间名称。我已经设置了表单以获取用户输入,然后我尝试重构它以在对话框中工作,我似乎停留在如何让对话框工作。这是我的整个组成部分:

import React, { Component } from 'react';
import './RoomList.css';
import dialogPolyfill from 'dialog-polyfill';

class RoomList extends Component {
  constructor(props) {
    super(props);
    this.state = { rooms: [] };
    this.roomsRef = this.props.firebase.database().ref('rooms');
    this.handleChange = this.handleChange.bind(this);
    this.createRoom = this.createRoom.bind(this);
  }

  handleChange(e){
    this.setState({ name: e.target.value });
  }

  createRoom(e) {
    e.preventDefault();
    this.roomsRef.push({ name: this.state.name });
    this.setState({ name: "" });
  }

  componentDidMount() {
    this.roomsRef.on('child_added', snapshot => {
      const room = snapshot.val();
      room.key = snapshot.key;
      this.setState({ rooms: this.state.rooms.concat( room ) });
    })
  }

  dialogBox(e){
    const dialogButton = document.getElementsByClassName('dialog-
    button');
    const dialog = document.getElementById('dialog');
    if (! dialog.showModal) {
      dialogPolyfill.registerDialog(dialog);
    }
    dialogButton.onClick( (e) => {
      dialog.showModal();
    });
    dialog.document.getElementsByClassName('submit-close').onCLick( 
    (e) => {
      dialog.close();
    });
  }


  render() {
    const roomlist = this.state.rooms.map( (room) =>
      <span className="mdl-navigation__link" key={room.key}>
      {room.name}</span>
    );

    const newListForm = (
      <div id="form">
        <button className="mdl-button mdl-js-button mdl-button--
        raised mdl-js-ripple-effect dialog-button">Add room</button>

        <dialog id="dialog" className="mdl-dialog">
          <h3 className="mdl-dialog__title">Create Room name</h3>
          <div className="mdl-dialog__content">
            <p>Enter a room name</p>
          </div>
          <div className="mdl-dialog__actions">
            <form onSubmit={this.createRoom}>
              <div className="mdl-textfield mdl-js-textfield">
                <input type="text" value={this.state.name} 
                className="mdl-textfield__input" id="rooms" onChange=
                {this.handleChange} />
                <label className="mdl-textfield__label" 
                htmlFor="rooms">Enter room Name...</label>
                <button type="submit" className="mdl-button submit-
                close">Submit</button>
                <button type="button" className="mdl-button submit-
                close">Close</button>
              </div>
            </form>
          </div>
        </dialog>
      </div>

    );
    return (
        <div className="layout mdl-layout mdl-js-layout mdl-layout--
        fixed-drawer mdl-layout--fixed-header">
          <header className="header mdl-layout__header mdl-color--
          grey-100 mdl-color-text--grey-600">
            <div className="mdl-layout__header-row">
              <span className="mdl-layout-title">Bloc Chat</span>
              <div className="mdl-layout-spacer"></div>
            </div>
          </header>
          <div className="drawer mdl-layout__drawer mdl-color--blue-
          grey-900 mdl-color-text--blue-grey-50">
            <header className="drawer-header">
              <span>{newListForm}</span>
            </header>
            <nav className="navigation mdl-navigation mdl-color--
            blue-grey-800">
              <div>{roomlist}</div>
              <div className="mdl-layout-spacer"></div>
            </nav>
          </div>
        </div>
    );
  }
}

export default RoomList;

2 个答案:

答案 0 :(得分:0)

以下是有关如何使用simple portal

提供的新portal API构建模态的简单示例

可以找到工作演示here。只需使用下拉菜单导航到import React, { Component } from "react"; import { createPortal } from "react-dom"; import "./simple-portal.css"; export default class SimplePortal extends Component { constructor() { super(); this.state = { list: [], input: "", showDialog: false }; this._onChange = this._onChange.bind(this); this._onSubmit = this._onSubmit.bind(this); } _onChange(e) { let input = e.target.value; this.setState({ input }); } _onSubmit(e) { e.preventDefault(); let showDialog = false; // Dont Mutate the State!!! let list = this.state.list.slice(); list.push(this.state.input); this.setState({ showDialog, list, input: "" }); } render() { const { showDialog, list, input } = this.state; return ( <div className="container"> <div> <button className="btn" onClick={e => this.setState({ showDialog: !showDialog }) } > Add Item </button> </div> {/* Render Items from List */} <div> <ul> {list.map(item => { return <li key={item}>{item}</li>; })} </ul> </div> {/* Show Modal - Renders Outside React Hierarchy Tree via Portal Pattern */} {showDialog === true ? ( <DialogModal> <div className="dialog-wrapper"> <h1>New List Item</h1> <form onSubmit={this._onSubmit}> <input type="text" value={input} onChange={this._onChange} /> </form> </div> </DialogModal> ) : null} </div> ); } } class DialogModal extends Component { constructor() { super(); this.body = document.getElementsByTagName("body")[0]; this.el = document.createElement("div"); this.el.id = "dialog-root"; } componentDidMount() { this.body.appendChild(this.el); } componentWillUnmount() { this.body.removeChild(this.el); } render() { return createPortal(this.props.children, this.el); } } 演示。可以在github上找到完整代码库的快照。

工作代码

const Data = require('./Models/Data');
...
let example = new Data( sample );
example.save( function ( err ){
  console.log('test);
  if ( err ) {
    console.log('Error saving Data. 'Error: ', err);
  }
});

答案 1 :(得分:0)

我没有在你的按钮上看到任何会触发模态渲染的事件监听器。我会通过指定一个onClick事件来处理这个问题,该事件将更新将呈现模态/对话框的状态。

另一种解决方案,可能是您的想法,就是让状态发生变化,以便在createRoom()函数中呈现模态/对话框。请记住,更新状态或获取新道具将触发组件的渲染。您正在尝试更新状态以重新渲染组件,并显示模式/对话框。

很抱歉,如果我误解了这个问题或你的目标。