在函数中设置状态不起作用-reactJs

时间:2018-10-30 21:08:54

标签: javascript reactjs

更新:在将数据发送到包含端点的updateEvent函数之前,我记录了三行代码。以下是日志:

  

新活动日期为2019-01-01T01:00:00.000

     

新的SET活动日期为:2019-01-01T01:00

     

事件详细信息为:{日期:“ 2019-01-01T01:00”…}

状态再次未设置为新格式​​。谁能看到错误可能是什么?

我正在尝试渲染事件日期以作为正文发送到端点。用户可以在TextInput字段中输入日期,但是在发送事件日期之前,我想使用时刻来修改其格式。 js在updateEvent cb中(YYYY-MM-DDTkk:mm:ss.SSS“),因此我创建了一个新变量

  

newDate

但是,updateEvent内部的setState并没有实际设置状态,而是保留了在handleEventInputChange中设置的date的值。我怀疑这可能是由于在handleEventInputChange和handleEvent内部两次将状态设置为相同的状态变量。谁能确认和/或提出解决方案?

 //... import and styles 
class EditEvent extends Component {
    constructor(props) {
        super(props);

        this.state = {
            event: {
                date: '',
            },
        };

        this.handleEventInputChange = this.handleEventInputChange.bind(this);
        this.updateEvent = this.updateEvent.bind(this);
    }

    handleEventInputChange(event) {
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

        this.setState({
            event: {
                ...this.state.event,
                [name]: value
            }
        });
    }

    updateEvent() {
        const { event } = this.state;
            let newDate = moment(this.state.event.date).format("YYYY-MM-DDTkk:mm:ss.SSS");

            this.setState(() => ({
                event: {
                    ...this.state.event,
                    date: newDate,
                }}))


            console.log("the new event date is ", newDate)
            console.log("the new SET event date is: ", event.date)
            console.log("the event detail is: ", event)

            this.props.updateEvent(this.props.event.id, event);
    }

    renderEvent() {
        const {
            event,
        } = this.state;

        return (
            <div>
                <Paper style={styles.paper}>
                    <TextField
                        name="date"
                        type="datetime-local"
                        onChange={this.handleEventInputChange}
                        value={event.date}/>
                </Paper>
            </div>
        );
    }

    render() {
        return (
            <ViewContainer
                title="Update Event"
                toolbarRight={
                    <Button
                        onClick={this.updateEvent}
                    > Save
                    </Button>
                }
            >
                {this.renderEvent()}
            </ViewContainer>
        );
    }
}

//... mapStateToProps, mapDispatchToProps and export default connect for EditEvent

2 个答案:

答案 0 :(得分:3)

根据您提供的代码,您试图在处理程序[name]: value的{​​{1}}中设置setState(),但是尚未设置handleEventInputChange(event)参数的赋值到event属性。您需要先在value的基础上添加一些内容,然后再将其传递给const value = target.value;

setState()

您还可以考虑使用解构:

handleEventInputChange(event) {
    const target = event.target;
    const name = target.name;
    const value = target.value; // add this

    this.setState({
        event: {
            ...this.state.event,
            [name]: value
        }
    });
}

更新handleEventInputChange(event) { const target = event.target; const { name, value } = target; this.setState({ event: { ...this.state.event, [name]: value } }); } 的{​​{1}}仅在onChange的所有部分都被 fire时包括日,月,年,小时,分钟和上午/下午。我创建了一个example来展示此功能的实际作用。更改了设置<input type="datetime-local" />的值的代码似乎可以正常工作。如果目标是始终显示格式化日期,则可以考虑创建另一个保留格式化值的状态属性,以避免在通过单击按钮触发<input type="datetime-local" />时更改value。这样,您可以避免不断覆盖this.state.event.date

更新2:基于这些评论,我将您试图解决的问题明确地归结为传递给映射动作分派的值。您可以尝试使用updateEvent()回调的第二个参数来调用this.state.event.date。关键是您将setState()传递到this.props.updateEvent()的第二个参数中,否则将传递旧的/原始的事件值。 example已更新以反映这一点。

this.event.state

希望有帮助!

答案 1 :(得分:1)

这是转发,原始答案为here

摘自React的documentation(在本文发布时)

  

setState()并不总是立即更新组件。它可能   批处理或将更新推迟到以后。这使得阅读this.state   在调用setState()之后立即陷入潜在的陷阱。

因此,不会,您的方法将不会在调用后立即从this.state 获取 setState的更新值,并且您无法在console.log中捕获更新后的值出于同样的原因。根据文档,更好的方法是使用componentDidUpdate

componentDidUpdate(prevProps, prevState) {
  if (this.event.date !== prevState.event.date) {
    this.props.updateEvent(this.props.event.id, event);
  }
}

updateEvent() {
  const { event } = this.state;
  let newDate = moment(this.state.event.date).format("YYYY-MM-DDTkk:mm:ss.SSS");

  this.setState(() => ({
      event: {
          ...this.state.event,
          date: newDate,
      }}))
}

如果您仍然坚持将this.props.updateEvent保留在updateEvent内,那么有两种方法可以实现:

(1)使用newDate代替this.state.event.date

updateEvent() {
  const { event } = this.state;
  let newDate = moment(this.state.event.date).format("YYYY-MM-DDTkk:mm:ss.SSS");

  this.setState(() => ({
      event: {
          ...this.state.event,
          date: newDate,
      }}))

  this.props.updateEvent(this.props.event.id, {
    ...this.state.event,
    date: newDate
  });
}

或(2)使用this.setState的回调正确获取更新后的值

updateEvent() {
  const { event } = this.state;
  let newDate = moment(this.state.event.date).format("YYYY-MM-DDTkk:mm:ss.SSS");

  this.setState(() => ({
      event: {
          ...this.state.event,
          date: newDate,
      }}),
      function callback() {
        this.props.updateEvent(this.props.event.id, this.state.event);
      }
  )
}