关闭后如何清除模态中的反应状态?

时间:2019-10-02 18:10:49

标签: javascript reactjs forms

我有一张产品卡,上面显示了产品详细信息。在底部,有一个“编辑” button。当clicked时,它会显示一个带有预填充input字段的模式,可以对其进行编辑然后保存。也可以在不保存(但输入字段已编辑)的情况下关闭模式。

  

我的问题是,当用户编辑字段然后关闭模式时   (不保存),然后再次将其打开,字段未设置为初始   值,但显示为已更改。

我尝试了一个具有初始状态的变量,然后在用它关闭状态填充后,但是它没有用。试图也回应裁判,没有喜悦。

import React, { Component } from 'react'
import Modal from 'react-modal';

const customStyles = {
...
};

Modal.setAppElement('#root');

class AdminButtons extends Component {

    state = {
        modalIsOpen: false,
    }

    componentDidMount() {
        const { id, inStock, name, price, type } = this.props.product
        this.setState({ id, inStock, name, price, type })
    }

    openModal = () => {
        this.setState({ modalIsOpen: true });
    }

    afterOpenModal = () => {
        ...
    }

    closeModal = () => {
        this.setState({ modalIsOpen: false });
    }

    handleChange = (event) => {
        const target = event.target
        const input = target.value
        const name = target.name
        this.setState({ [name]: input })
    }

    render() {
        const { product, remove } = this.props
        const { modalIsOpen, name, inStock, price, type } = this.state
        return (
            <>
                <button onClick={this.openModal}>EDIT</button>
                <Modal
                    isOpen={modalIsOpen}
                    onAfterOpen={this.afterOpenModal}
                    style={customStyles}
                    contentLabel="Edit "
                >
                    <h2 ref={subtitle => this.subtitle = subtitle}>Hello</h2>
                    <button onClick={this.closeModal}>close</button>
                    <div>{this.props.product.name}</div>
                    <form>
                        <label>
                            Name
                            <input name="name" type="text" value={name} onChange={this.handleChange} />
                        </label>
                        <label>inStock
                            <input name="inStock" type="text" value={inStock} onChange={this.handleChange} />
                        </label>
                        <label>
                            Price
                            <input name="price" type="text" value={price} onChange={this.handleChange} />
                        </label>
                        <label>
                            Type
                            <input name="type" type="text" value={type} onChange={this.handleChange} />
                        </label>
                        <button onClick={ () => {
                            this.props.edit(this.state)
                            this.closeModal() }
                            }>Save changes</button>
                    </form>
                </Modal>
                {product.isRemoved ?
                    <button> add </button> :
                    <button onClick={() => remove(product.id)}>remove</button>
                }
            </>
        )
    }
}

3 个答案:

答案 0 :(得分:1)

如果来自输入的数据在您的组件中,则可以尝试如下操作: 在closeModal中,您可以设置组件的初始状态


const initialState = { name: null, inStock: null, price: null, type:null }

closeModal = () => {
        this.setState({ 
         ...initialState,
         modalIsOpen: false 
        });
    }

但是,如果输入的统计信息来自父级,则需要一种新方法来重置父级组件的数据,该组件应以相同的方法作为回调添加。

const initialState = { name: null, inStock: null, price: null, type:null }

closeModal = () => {
        this.setState({ 
         modalIsOpen: false 
        }, () => {
        this.props.resetInputData();
      });
    }

答案 1 :(得分:0)

我不是该解决方案的唯一创建者,但是对于仍然遇到此问题的任何人,它都与该主题相关。

我所做的是添加了一个名为useTimeout的新钩子变体,它本身非常易于使用,并将为您重置状态。

  1. 将名为“ hooks”的文件夹作为子级添加到您的src文件夹
  2. 在“ hooks”文件夹中创建一个名为useTimeout.tsx的文件
  3. 复制以下代码粘贴useTimeout代码。

import React from 'react';

export function useTimeout(callback: () => void, delay: number | null | undefined) {
    const timeoutRef = React.useRef<number | undefined>();
    const callbackRef = React.useRef<any>(callback);
  
    // Remember the latest callback:
    //
    // Without this, if you change the callback, when setTimeout kicks in, it
    // will still call your old callback.
    //
    // If you add `callback` to useEffect's deps, it will work fine but the
    // timeout will be reset.
  
    React.useEffect(() => {
      callbackRef.current = callback;
    }, [callback]);
  
    // Set up the timeout:
  
    React.useEffect(() => {
      if (typeof delay === 'number') {
        timeoutRef.current = window.setTimeout(() => callbackRef.current(), delay);
  
        // Clear timeout if the components is unmounted or the delay changes:
        return () => window.clearTimeout(timeoutRef.current);
      }

      return () => null;
    }, [delay]);
  
    // In case you want to manually clear the timeout from the consuming component...:
    return timeoutRef;
  }

  1. 在模态组件内部,导入useTimeout挂钩,如下所示:

    import { useTimeout } from '../../../hooks/useTimeout';

  2. 在组件的return()上方使用它,如下所示:

    useTimeout(() => reset state), activate when true ? when true wait milliseconds before : null);

    示例: useTimeout(() => setState({ ...state, currentStep: '' }), !props.open ? 350 : null);

答案 2 :(得分:-1)

您可以使用componentwillunmont,React组件lifecycle

  

componentwillunmount (当您从某个组件中退出时)   运行。

例如:

componentwillunmount() {
   alert("do you want to exit?");
}

此外,您可以阅读有关React生命周期herehere的更多信息。