React新手求助:点击子组件按钮如何重新渲染父组件?
解答你的React组件交互问题
Hey there! Great question, and let's start with the big one: 保持子组件无状态是完全合理且推荐的做法!这种把展示逻辑和数据/业务逻辑分离的方式是React的核心最佳实践之一——子组件只负责接收props来展示内容,以及触发父组件传入的回调处理用户交互,而父组件管理状态和数据获取,这样你的组件职责清晰,复用性和可维护性都会更好。
接下来看你当前代码的问题:你用了forceUpdate(),但这个方法确实不推荐(你自己也知道啦),而且更关键的是,点击按钮后并没有重新发起请求获取新的活动数据——因为componentDidMount只在组件挂载时执行一次,强制更新父组件并不会重新调用这个方法,所以你的activity状态不会变化,子组件自然也不会展示新内容。
这里给你一个更符合React规范的改进方案:
改进后的父组件代码
import React, { Component } from 'react'; import Activity from './Components/Activity' class App extends Component { state = { activity: '' } // 把获取活动数据的逻辑抽成单独方法 fetchNewActivity = async () => { const url = 'http://www.boredapi.com/api/activity/' const response = await fetch(url); const data = await response.json(); this.setState({ activity: data.activity }) } // 组件挂载时首次获取数据 componentDidMount() { this.fetchNewActivity(); } // 点击按钮时调用获取新数据的方法 handleClick = () => { this.fetchNewActivity(); } render() { return ( <div> <Activity act={this.state.activity} click={this.handleClick}/> </div> ); } } export default App;
子组件代码可以保持不变
import React, { Component } from 'react'; class Activity extends Component { render() { return ( <div> <h1>Bored? Here is something to do</h1> <p>{this.props.act}</p> <button onClick={this.props.click}>Something Else</button> </div> ); } } export default Activity;
为什么这样更好?
- 完全抛弃了
forceUpdate(),遵循React的状态更新机制:当你调用setState更新activity状态时,React会自动重新渲染父组件,进而更新子组件的props,触发子组件重新渲染,这是React的正常数据流。 - 数据获取逻辑复用:把请求逻辑抽成单独方法后,不管是组件初始化还是用户点击按钮,都可以复用这段代码,避免重复。
- 子组件依然保持“无状态”(或者说纯展示组件),它不需要关心数据从哪里来、怎么更新,只需要做好展示和传递用户操作的工作,这样这个子组件可以很容易地在其他地方复用,只要传入对应的
act和clickprops就行。
如果之后你想进一步优化,还可以把子组件改成函数式组件(因为它没有自己的状态和生命周期),会更简洁:
import React from 'react'; const Activity = ({ act, click }) => { return ( <div> <h1>Bored? Here is something to do</h1> <p>{act}</p> <button onClick={click}>Something Else</button> </div> ); } export default Activity;
总的来说,你的思路是对的,保持子组件无状态是非常好的做法,只需要调整父组件的数据更新逻辑,抛弃forceUpdate,让React的状态机制帮你处理渲染就好啦!
内容的提问来源于stack exchange,提问作者stucklucky
相关产品推荐
相关产品推荐

