首页 > 解决方案 > 方法在代码中没有按预期工作 - Reactjs

问题描述

目标:
使用代码应用这个新的 js 文件 (displayModalContent.js),并且应用程序应该可以正常使用而不会出现任何错误。(来自stackblitz之后或之后)

问题:
重构后我无法使用新的 js 文件。模态不显示。我错过了什么?

Stackblitz 之前:
https ://stackblitz.com/edit/react-8schc7 ?

Stackblitz 之后:
https ://stackblitz.com/edit/react-kcwy7a ?


前:

import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import Modal from 'react-modal';
import Select from 'react-select';

const options = [
  { value: 1, label: 'Jan' },
  { value: 2, label: 'Feb' },
  { value: 3, label: 'Mars' },
  { value: 4, label: 'April' },
  { value: 5, label: 'May' },
  { value: 6, label: 'June' },
  { value: 7, label: 'July' },
  { value: 8, label: 'August' },
  { value: 9, label: 'Sept' },
  { value: 10, label: 'Oct' },
  { value: 11, label: 'Nov' },
  { value: 12, label: 'Dec' }
];

class App extends Component {
  constructor() {
    super();

    this.state = {
      openItem: null,
      items: [
        {
          firstName: 'Josef',
          lastName: 'Anderson',
          key: 'josef.anderson',
          startYear: 2021,
          startMonth: 2
        },
        {
          firstName: 'Jim',
          lastName: 'West',
          key: 'jim.west',
          startYear: 2020,
          startMonth: 3
        },
        {
          firstName: 'Joe',
          lastName: 'West',
          key: 'joe.west',
          startYear: 1998,
          startMonth: 10
        }
      ],
      firstName: '',
      lastName: ''
    };
  }

  handleOpenModal = openItem => {
    this.setState({ openItem });
  };

  handleCloseModal = () => {
    this.setState({ openItem: null });
  };

  handleOpenItemValue = e => {
    let { name, value } = e.target;
    this.setState({
      openItem: { ...this.state.openItem, [name]: value }
    });
  };

  handleSubmit = () => {
    console.log(document.getElementsByName('startMonth')[0].value);
    alert(
      JSON.stringify({
        test: document.getElementsByName('startMonth')[0].value
      })
    );
  };

  render() {
    const { items, openItem } = this.state;

    return (
      <div>
        <table border="1">
          <thead>
            <tr>
              <th>First Name</th>
              <th>Last Name</th>
              <th />
            </tr>
          </thead>
          <tbody>
            {items.map(item => {
              const { firstName, lastName, key } = item;

              return (
                <tr key={key}>
                  <td>{firstName}</td>
                  <td>{lastName}</td>
                  <td>
                    <button onClick={() => this.handleOpenModal(item)}>
                      Open Modal
                    </button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
        <div>
          {openItem !== null && (
            <Modal className="confirmation-modal" isOpen={true}>
              First Name:
              <br />
              <input
                type="text"
                id="firstName"
                name="firstName"
                value={openItem.firstName}
                onChange={e => this.handleOpenItemValue(e)}
              />
              <input
                type="text"
                id="lastName"
                name="lastName"
                value={openItem.lastName}
                onChange={e => this.handleOpenItemValue(e)}
              />
              <Select
                defaultValue={options.find(
                  option => option.value === openItem.startMonth
                )}
                name="startMonth"
                id="testaaa"
                options={options}
              />
              <button onClick={this.handleCloseModal}>Close Modal</button>
              <button onClick={this.handleSubmit}>Test</button>
            </Modal>
          )}
        </div>
      </div>
    );
  }
}

Modal.setAppElement(document.getElementById('root'));
render(<App />, document.getElementById('root'));

h1,
p {
  font-family: Lato;
}

.confirmation-overlay.ReactModal__Overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
  background-color: rgba(0, 0, 0, 0.6);
}

.confirmation-overlay.ReactModal__Overlay--after-open {
  opacity: 1;

  transition: opacity 300ms ease-out;
}

.confirmation-modal.ReactModal__Content {
  position: absolute;

  top: 25%;
  left: 50%;
  width: 500px;
  right: auto;
  bottom: auto;
  border: 1px solid #eee;
  margin-right: -50%;
  transform: scale(0);
  background-color: #fff;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  outline: none;
  padding: 20px;
  opacity: 0;
}

.confirmation-modal.ReactModal__Content--after-open {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
  transition: all 300ms ease-out;
}

.confirmation-modal button {
  border: 1px solid black;
  background-color: #fff;
  color: #333;
  padding: 4px 8px;
  margin: 4px;
  border-radius: 3px;
  cursor: pointer;
}

.confirmation-modal button:hover {
  background-color: #eee;
}

后:

import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import Modal from 'react-modal';
import Select from 'react-select';
import DisplayModalContent from './displayModalContent';

class App extends Component {
  constructor() {
    super();

    this.state = {
      openItem: null,
      items: [
        {
          firstName: 'Josef',
          lastName: 'Anderson',
          key: 'josef.anderson',
          startYear: 2021,
          startMonth: 2
        },
        {
          firstName: 'Jim',
          lastName: 'West',
          key: 'jim.west',
          startYear: 2020,
          startMonth: 3
        },
        {
          firstName: 'Joe',
          lastName: 'West',
          key: 'joe.west',
          startYear: 1998,
          startMonth: 10
        }
      ],
      firstName: '',
      lastName: ''
    };
  }

  handleOpenModal = openItem => {
    this.setState({ openItem });
  };

  handleCloseModal = () => {
    this.setState({ openItem: null });
  };

  handleOpenItemValue = e => {
    let { name, value } = e.target;
    this.setState({
      openItem: { ...this.state.openItem, [name]: value }
    });
  };

  handleSubmit = () => {
    console.log(document.getElementsByName('startMonth')[0].value);
    alert(
      JSON.stringify({
        test: document.getElementsByName('startMonth')[0].value
      })
    );
  };

  render() {
    const { items, openItem } = this.state;

    return (
      <div>
        <table border="1">
          <thead>
            <tr>
              <th>First Name</th>
              <th>Last Name</th>
              <th />
            </tr>
          </thead>
          <tbody>
            {items.map(item => {
              const { firstName, lastName, key } = item;

              return (
                <tr key={key}>
                  <td>{firstName}</td>
                  <td>{lastName}</td>
                  <td>
                    <button onClick={() => this.handleOpenModal(item)}>
                      Open Modal
                    </button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>

        <DisplayModalContent item={openItem} />
      </div>
    );
  }
}

Modal.setAppElement(document.getElementById('root'));
render(<App />, document.getElementById('root'));

之后(displayModalContent.js):

import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import Modal from 'react-modal';
import Select from 'react-select';

const options = [
  { value: 1, label: 'Jan' },
  { value: 2, label: 'Feb' },
  { value: 3, label: 'Mars' },
  { value: 4, label: 'April' },
  { value: 5, label: 'May' },
  { value: 6, label: 'June' },
  { value: 7, label: 'July' },
  { value: 8, label: 'August' },
  { value: 9, label: 'Sept' },
  { value: 10, label: 'Oct' },
  { value: 11, label: 'Nov' },
  { value: 12, label: 'Dec' }
];

class displayModalContent extends Component {
  constructor() {
    super();

    this.state = {
      openItem: null,
      firstName: '',
      lastName: ''
    };
  }

  handleOpenModal = openItem => {
    this.setState({ openItem });
  };

  handleCloseModal = () => {
    this.setState({ openItem: null });
  };

  handleOpenItemValue = e => {
    let { name, value } = e.target;
    this.setState({
      openItem: { ...this.state.openItem, [name]: value }
    });
  };

  handleSubmit = () => {
    console.log(document.getElementsByName('startMonth')[0].value);
    alert(
      JSON.stringify({
        test: document.getElementsByName('startMonth')[0].value
      })
    );
  };

  render() {
    const { items, openItem } = this.state;

    return (
      <div>
        {openItem !== null && (
          <Modal className="confirmation-modal" isOpen={true}>
            First Name:
            <br />
            <input
              type="text"
              id="firstName"
              name="firstName"
              value={openItem.firstName}
              onChange={e => this.handleOpenItemValue(e)}
            />
            <input
              type="text"
              id="lastName"
              name="lastName"
              value={openItem.lastName}
              onChange={e => this.handleOpenItemValue(e)}
            />
            <Select
              defaultValue={options.find(
                option => option.value === openItem.startMonth
              )}
              name="startMonth"
              id="testaaa"
              options={options}
            />
            <button onClick={this.handleCloseModal}>Close Modal</button>
            <button onClick={this.handleSubmit}>Test</button>
          </Modal>
        )}
      </div>
    );
  }
}

export default displayModalContent;

标签: javascriptreactjs

解决方案


您必须添加生命周期方法才能在 displayModalContent.js 文件中填充 openItem

  componentDidUpdate(s, p) {
    if (JSON.stringify(this.props) !== JSON.stringify(s)) {
      this.setState({ openItem: this.props.item });
    }
  }

推荐阅读