我创建了两个输入。在第二分钟,我选择一个小时。当我单击“编辑”时,小时和分钟应显示在输入中,并转换为每小时600分钟。您要编辑的时间应显示在进样中。我不想更改任何内容。给您节省。小时保持不变。
此处的代码:https://stackblitz.com/edit/react-uadnrj
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>
)
}
}
答案 0 :(得分:1)
您缺少class constructor。设置状态或插入道具时,需要在班级组件的开头使用它。您在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'));