温馨提示:本文翻译自stackoverflow.com,查看原文请点击:javascript - Own time picker does not take the default value
javascript reactjs

javascript - 自己的时间选择器不采用默认值

发布于 2020-03-27 11:03:37

我创建了两个输入。在第二分钟,我选择一个小时。当我单击编辑时,小时和分钟应显示在输入中,并转换为每小时600分钟。您要编辑的时间应显示在进样中。我不想更改任何内容。给您节省。时间保持不变。

代码在这里:https : //stackblitz.com/edit/react-uadnrj

图片:https : //imgur.com/zF18gXh

class EditForm extends React.Component {
  render() {
    return (
      <div className="asd">
        Hours:
        <input type="number" defaultValue={this.props.displayH}onChange={(e) => this.props.handleHours(e)} value={this.props.displayH} />
        Minutes: 
         <input type="number"  defaultValue={this.props.displayH} onChange={(e) => this.props.handleMinutes(e)} value={this.props.displayM} />
        <button onClick={this.props.onSave} type="submit">Save</button>
        <button onClick={this.props.onCancel} type="submit">Cancel</button>
      </div>
    )
  }
}


class Todo extends Component {

  state = {
    isEditing: false,
    displayH: '',
    displayM: '',
    hours: '',
    minutes: '',
    seconds: ''
  }



  displayHours = (item) => {
    let d = Number(item);
    let hours = Math.floor(d / 3600);

    return hours; 
  }

  displayMinutes = (item) => {
    let d = Number(item);
    let minutes = Math.floor(d % 3600 / 60);

    return minutes; 
  }


  setEditing = () => {
    this.setState({
      isEditing: !this.state.isEditing
    })
  }

  handleHours = (hours) => {
    this.setState({
      displayH: this.displayHours(hours),
      hours: hours * 60 * 60
    })
    console.log('changed', hours);
  }

  handleMinutes = (minutes) => {
    this.setState({
      displayM:  this.displayMinutes(minutes),
      minutes: minutes * 60
    })
    console.log('changed', minutes);
  }


  onSave = () => {

    const { description } = this.state;

    this.props.update(this.props.index, { seconds});

    this.setState({
      isEditing: false
    })
  }

  onCancel = () => {
    this.setState({
      isEditing: false,
    });
  }

  componentDidMount = () => {
    const { todo } = this.props;

    this.setState({
      seconds: todo.seconds
    })
  }

  render() {

    return (
      <div>
        {this.state.isEditing

          ? (<EditForm
            handleHours={this.handleHours}
            handleMinutes={this.handleMinutes}
            onSave={this.onSave}
            onCancel={this.onCancel}
            displayH = {this.state.displayH}
            displayM = {this.state.displayM}
          />)
          : (
            <li>
              <h1>{this.state.displayH}  {this.state.displayM}</h1>
              <button onClick={() => this.setEditing()}>Edit</button>
            </li>
          )

        }
      </div>
    )
  }
}

查看更多

查看更多

提问者
Umbro
被浏览
259
Michael Cox 2019-07-03 23:24

您缺少类的构造函数设置状态或插入道具时,需要在班级组件的开头使用它。您已经在App中拥有它,但是在Todo中却找不到它。例如Todos会像这样:

class Todo extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isEditing: false,
      displayH: '',
      displayM: '',
      hours: '',
      minutes: '',
      seconds: ''
    };
  }

  //...the rest of your code
}

对于没有任何状态变量的组件,可以通过将它们转换为功能组件来简化它们:

const CustomInput = props => (
  <div className="wrapper">
    <i onClick={props.onClick} aria-hidden="true" className="fa fa-calendar"></i>
    <input onClick={props.onClick} className="dateInput" value={props.value} type="text" />
  </div>
);

另外,请记住,输入的onChange返回一个事件,而不是值。因此,您处理函数需要解析事件:

  handleMinutes = ({ target: { value: minutes }}) => {
    this.setState({
      displayM:  this.displayMinutes(minutes),
      minutes: minutes * 60
    })
    console.log('changed', minutes);
  }

我不得不重做很多组件,但是我确实可以正常工作。这是代码:

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";

class EditForm extends Component {
  constructor(props) {
    super(props);
    console.log(props);

    this.state = {
      hours: props.displayH,
      minutes: props.displayM,
    };
  }

  handleHours = ({ target: { value: hours }}) => {
    this.setState({
      hours,
    });
  }

  handleMinutes = ({ target: { value: minutes }}) => {
    this.setState({
      minutes,
    })
    console.log('changed', minutes);
  }

  render() {
    const { hours, minutes } = this.state;
    return (
      <div className="asd">
        Hours:
        <input type="number" value={hours} onChange={this.handleHours} />
        Minutes: 
          <input type="number"  value={minutes} onChange={this.handleMinutes} />
        <button onClick={() => this.props.onSave(hours, minutes)} type="submit">Save</button>
        <button onClick={this.props.onCancel} type="submit">Cancel</button>
      </div>
    )
  }
}

class Todo extends Component {
  constructor(props) {
    super(props);
    console.log(props);

    const { seconds } = props.todo;

    const displayH = Math.floor(Number(seconds) / 3600) ?
      Math.floor(Number(seconds) / 3600) :
      '';

    const displayM = Math.floor(Number(seconds) % 3600 / 60) ?
      Math.floor(Number(seconds) % 3600 / 60) :
      '';

    this.state = {
      isEditing: false,
      displayH,
      displayM,
    };
  }

  componentDidUpdate(prevProps) {
    const { seconds } = this.props.todo;
    const { seconds: prevSeconds } = prevProps.todo;
    // Typical usage (don't forget to compare props):
    if (seconds !== prevSeconds) {
      const displayH = Math.floor(Number(seconds) / 3600) ?
        Math.floor(Number(seconds) / 3600) :
        '';

      const displayM = Math.floor(Number(seconds) % 3600 / 60) ?
        Math.floor(Number(seconds) % 3600 / 60) :
        '';
      this.setState({
        displayH,
        displayM,
      });
    }
  }

  setEditing = () => {
    this.setState({
      isEditing: !this.state.isEditing
    });
  }

  onSave = (hours, minutes) => {
    console.log('saving', hours, minutes);

    const seconds = (hours * 60 * 60) + (minutes * 60);

    this.props.update(this.props.index, { seconds });

    this.setState({
      isEditing: false
    })
  }

  onCancel = () => {
    this.setState({
      isEditing: false,
    });
  }

  componentDidMount = () => {
    const { todo: { seconds } } = this.props;

    this.setState({
      seconds
    })
  }

  render() {
    const { displayH, displayM } = this.state;
    console.log('rendering Todo');

    return (
      <div>
        {this.state.isEditing

          ? (
            <EditForm
              handleHours={this.handleHours}
              handleMinutes={this.handleMinutes}
              onSave={this.onSave}
              onCancel={this.onCancel}
              displayH = {displayH}
              displayM = {displayM}
            />
          )
          : (
            <li>
              <h1>
                { displayH && `${displayH}h` }
                { displayM && `${displayM}m` }</h1>
              <button onClick={() => this.setEditing()}>Edit</button>
            </li>
          )

        }
      </div>
    )
  }
}

class App extends React.Component {
  constructor() {
    this.state = {
      todos: [
        {
          seconds: 600
        }
      ]
    };
  }

  update = (index, todo) => {
    console.log('updating', todo, index);
    this.setState({
      todos: [
        ...this.state.todos.slice(0, index),
        Object.assign({}, this.state.todos[index], todo),
        ...this.state.todos.slice(index + 1)]
    })
  }

  render() {
    console.log('rendering App');
    return (
      <div>
        <ul>
          {
            this.state.todos
              .map((todo, index) =>
                <Todo
                  key={index}
                  index={index}
                  todo={todo}
                  update={this.update}
                />
              )
          }
        </ul>
      </div>
    );
  }
}
render(<App />, document.getElementById('root'));