You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React子组件向父组件传递对象多数据及触发异常解决

问题分析与解决方案

Hey there, let's fix this issue where your updatedPostsHandler is triggering on every input change instead of only when the "Add Post" button is clicked!

The Root Cause

The problem lies in your NewPost component's button code:

<button onClick={this.props.newPostCreated(this.state.post)}> Add Post </button>

When you write this.props.newPostCreated(this.state.post) directly inside the onClick prop, you're immediately executing the function during component rendering (and every time the component re-renders, like when input values change). This isn't what you want—you need to pass a function that will only run when the button is clicked.

Fix 1: Wrap the Call in an Arrow Function

Change the button's onClick to pass an arrow function that calls the parent method when clicked:

<button onClick={() => this.props.newPostCreated(this.state.post)}> Add Post </button>

This way, newPostCreated only runs when the button is clicked, not on every re-render.

Bonus Fix: Avoid Unnecessary State Updates

You also have a small issue in your handleChange method: since setState is asynchronous, when you update the post state using this.state.title/content/author, you're actually using the previous state values (not the ones you just typed).

A cleaner approach is to remove the post property from your NewPost state entirely, and construct the post object only when the button is clicked. This reduces unnecessary state updates and avoids async state bugs:

Updated NewPost Component

class NewPost extends Component {
  state = {
    title: '',
    content: '',
    author: 'Max'
    // Remove the 'post' property here
  }

  handleChange = (event) => {
    this.setState({
      [event.target.name]: event.target.value
      // No need to update 'post' here anymore
    });
  }

  render() {
    return (
      <div className="NewPost">
        <h1>Add a Post</h1>
        <label>Title</label>
        <input 
          type="text" 
          name="title" 
          value={this.state.title} 
          onChange={this.handleChange} 
        />
        <label>Content</label>
        <textarea 
          rows="4" 
          name="content" 
          value={this.state.content} 
          onChange={this.handleChange} 
        />
        <label>Author</label>
        <select 
          name="author" 
          value={this.state.author} 
          onChange={this.handleChange}
        >
          <option value="Max">Max</option>
          <option value="Manu">Manu</option>
        </select>
        {/* Construct the post object directly when clicking */}
        <button onClick={() => this.props.newPostCreated({
          title: this.state.title,
          content: this.state.content,
          author: this.state.author
        })}> 
          Add Post 
        </button>
      </div>
    );
  }
}

Why This Works

  1. The arrow function in onClick acts as a wrapper—only when the button is clicked does it execute newPostCreated with the current input values.
  2. By constructing the post object on click instead of updating it on every input change, you eliminate redundant state updates and avoid issues with asynchronous setState.

Your parent component (Blog) doesn't need any changes—this fix will ensure updatedPostsHandler only runs when the button is clicked, just like you intended!

内容的提问来源于stack exchange,提问作者Tanvir Rahman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:27:05