代码之家  ›  专栏  ›  技术社区  ›  Db12797

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

  •  0
  • Db12797  · 技术社区  · 7 年前

    我正在使用React和firebase创建简化的slack,并将MDl用于样式。我正在尝试集成一个按钮,该按钮打开一个对话框以获得一些用户输入,在本例中是一个新聊天室的名称,然后在提交时,它将数据发送到firebase并存储在rooms数组中,并在列表中显示新聊天室的名称。我已经将表单设置为获取用户输入,然后我尝试将其重构为在对话框中工作,我似乎被困在了如何使对话框工作的问题上。这是我的全部组成部分:

    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 回复  |  直到 7 年前
        1
  •  1
  •   canaan seaton    7 年前

    下面是一个关于如何使用新 portal API 提供自 React v16.xx

    可以找到工作演示 here . 只需使用下拉菜单导航到 simple portal 演示。完整代码库的快照可以在上找到 github .

    工作代码

    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);
        }
    }
    
        2
  •  0
  •   Logan Shoemaker    7 年前

    我在您的按钮上没有看到任何会触发模式渲染的事件侦听器。我将通过指定onClick事件来实现这一点,该事件将更新呈现模式/对话框的状态。

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

    抱歉,如果我误解了问题或您的目标。