React 组件接收到错误的道具值

jsdev17

我有一个 Modal 组件和一个 Form 组件。Modal 是一个功能组件,而 Form 是一个类组件,因为这是我处理表单提交的地方。

Modal [父级] 将其所有道具传递给 Form。Modal 的 props 对象中有三个值,两个字符串和一个数字。

字符串值符合预期,但数字(用作 id)为 1,而不是预期的 10(在本例中)。这是一个问题,因为我试图将该值保存到状态中,并且没有得到我期望的值。

奇怪的是,如果 Iconsole.log(this.props)在里面render()props 对象会打印两次第一次数字值为 1,第二次为 10。这发生在组件的初始渲染时,状态不会发生任何变化。

为什么会发生这种情况,我如何获得我期望的实际价值?


这是模态组件。

import React from 'react';
import Form from './Form';


const Modal = (props) => (
  <div className="modal fade" id="createWorkitem" tabIndex="-1" role="dialog" aria-labelledby="createWorkitemLabel" aria-hidden="true">
    <div className="modal-dialog" role="document">
      <div className="modal-content">
        <div className="modal-header">
          <h5 className="modal-title" id="createWorkitemLabel">
            {/* 10 */}
            Item #{ props.issueNumber }
          </h5>
          <button type="button" className="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div className="modal-body">
          {/* Form needs props to POST */}
          <Form
            {...props}
          />
        </div>
      </div>
    </div>
  </div>
);

export default Modal;

这是表单组件

import React, { Component } from 'react';
import axios from 'axios';
import config from '../../../../../config';
const { create_issue_url } = config.init();

class Form extends Component {
  constructor(props) {
    super(props);
    this.state = {
      issueNumber: '',
      title: '',
      price: '',
      duration: '',
      description: ''
    }

    this.handleChange = this.handleChange.bind(this);
    this.submitForm = this.submitForm.bind(this);
    this.resetForm = this.resetForm.bind(this);
  }

  componentWillMount() {
    // this prints once with wrong value
    console.log(this.props);
  }

   componentDidMount() {
    // this prints once with wrong value
    console.log(this.props);
    // this prints once with right value inside props object
    console.log(this);
  }

  handleChange(e) {
    this.setState({[e.target.id]: e.target.value});
  }

  submitForm(e) {
    e.preventDefault();
    let endpoint = `${create_issue_url}/${this.props.repo}`;
    let msg = 'Are you sure you want to create this item?';
    // Make sure
    if(confirm(msg)) {
      axios.post(endpoint, this.state)
      .then(response => {
        console.log(response.data.workitem);
        // Clear form
        this.resetForm();
        // Show success alert
        document.getElementById('successAlert').style.display = '';
        // Hide it after 3 seconds
        setTimeout(function hideAlert(){
          document.getElementById('successAlert').style.display = 'none';
        }, 3000);
      })
      .catch(err => {
        console.log(err);
      });
    }
  }

  resetForm() {
    this.setState({
      title: '',
      price: '',
      duration: '',
      description: ''
    });
  }

  render() {
    let { title, price, duration, description } = this.state;
    // this prints twice
    {console.log(this.props.issueNumber)}
    return (
      <form onSubmit={this.submitForm}>
        <div id="successAlert" className="alert alert-success" role="alert"
          style={{display: 'none'}}
        >
          Item created.
        </div>
        <div className="form-row">
          <div className="form-group col-md-6">
            <label htmlFor="title">Title</label>
            <input onChange={this.handleChange} type="text" value={title} className="form-control" id="title" required/>
          </div>
          <div className="form-group col-md-3">
            <label htmlFor="price">Price</label>
            <input onChange={this.handleChange} type="number" value={price} className="form-control" id="price" required/>
          </div>
          <div className="form-group col-md-3">
            <label htmlFor="duration">Duration</label>
            <input onChange={this.handleChange} type="number" value={duration} className="form-control" id="duration"
              placeholder="days" required
            />
          </div>
        </div>
        <div className="form-group">
          <label htmlFor="description">Description</label>
          <textarea
            onChange={this.handleChange} 
            className="form-control"
            id="description"
            style={{overflow: 'auto', resize: 'none'}}
            value={description}
            required
          ></textarea>
        </div>
        {/* Using modal footer as form footer because it works */}
        <div className="modal-footer">
          <button type="submit" className="btn btn-primary">Submit</button>
          <button type="button" className="btn btn-secondary" data-dismiss="modal">Close</button>
        </div>
      </form>
    ); 
  }

}

export default Form;
苏宾塞巴斯蒂安

行为是正确的。在加载时,您的模态组件将接收 props 为 1。后来它更改为 10。因此,一旦值更改为 10,您的组件就会更新。在初始安装期间,componentDidMount 将仅被调用一次。但是只要组件更新即收到更新的道具(在您的情况下问题编号 10),就会调用 componentDidUpdate 和 render 。

所以 render 最初会被调用两次,1 作为 prop 值,然后是 10。但是 componentDidMount 只会被调用一次(当 prop 值为 1 时)

现在是在 componentDidMount 中打印 console.log(this) 与 console.log(this.props) 的问题。第一种情况显示 issuenumber prop 为 10,第二种情况显示为 1。我怀疑这是因为 chrome 开发人员工具正在使用实时更新优化打印。当您打印时,this显然 prop 为 1,但是我觉得控制台正在实时更新该打印(因为该对象很快就会用新的 props 更新)

Console.log 仅显示打印对象的更新版本

正如这里所建议的,而不是console.log(this)尝试console.log(JSON.parse(JSON.stringify(this)));这应该打印 1

希望这可以解决问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用路由传递道具时,无法在 react Js 的组件中接收到 URL 参数

组件调试道具 - react redux - 子组件接收非设置值

嵌套的React / Relay组件未接收道具

React-接收新道具时子组件不会更新

React-native const组件不接收道具?

如何正确编写可以接收道具的React类组件?

React组件收到的道具,但未在JSX中更新

React Native 子组件未收到更新的道具

React Native-收到道具时测量组件

Redux 商店更新后,React 组件未收到道具

React 道具和组件

为什么没有通过 react-router 中的链接收到道具

React Native Navigation(ver4.x)无法在自定义标头组件中获取道具。不断收到未定义的错误

React组件为作为道具传入的函数抛出TypeScript错误

React + TypeScript:将React组件作为道具传递,使用道具进行渲染[错误:TS2339]

将React组件作为对象值返回并绑定道具

使用react-transition-group作为子组件接收新道具

Redux开发工具中会收到Redux道具,但React组件中不会

React 子组件在第一次加载时不会收到道具

React功能组件未接收到异步数据,似乎停止运行中间功能

谷歌地图API接收到的react组件更新数据中的setState问题

在onChange事件从Paste(ctrl + v)接收到数据后,React Initiating组件重新呈现

尝试在 React 中的功能组件内使用道具时,我收到 TypeError:无法设置未定义的属性“道具”?

React组件中的儿童道具

React 组件访问道具

自动映射React组件的道具

React - 向组件发送道具

React-Redux设计模式:应该将“深层”组件连接到Redux,还是从父组件接收道具?

React Js:将道具传递给 React Router 的 Link 组件错误