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

React-Redux中Props更新后函数未即时触发状态更新的问题求助

问题:React-Redux Connect传递Props后,子组件状态无法即时更新

我通过react-redux的connect从mapStateToProps获取props,将其传递给子组件。该props作为函数参数,函数返回值作为子组件的状态。我确认props已更新(页面显示正确),但函数未即时更新状态,需切换react-router路由再返回才生效。请问如何实现即时更新?是否做法有误?求指导。

附代码:

import React, { Component } from 'react';
import {connect} from "react-redux";
import filterData from "../../States/AllStates/filterData"
import BookComponent from "./BookComponent";
const mapStateToProps = state => {
 return { fmlProps: state.ReducerName.fmlProps }
};
class Testing extends Component {
 state = {
 // this.props.fmlPropsdoesn't work right away. You need to go away then come back
 // to see the desired result, which I want to avoid
 XXX: filterData(this.props.fmlProps)
 }
 render() {
 return (
 <>
 <h1>{this.props.fmlProps}</h1> {/* this show up correct */}
 {this.state.XXX.map(FakeData => (
 <BookComponent key={FakeData.planNumber} PNum={FakeData.planNumber} PName={FakeData.planName} />
 ))}
 </>
 );
 }
}
export default connect(mapStateToProps, null) (Testing);

解答

嘿,我来帮你捋清楚问题所在:你现在的写法里,state.XXX只在组件第一次初始化的时候赋值了一次!也就是说,当this.props.fmlProps从Redux store更新时,组件的state并不会自动跟着重新计算——只有当组件被卸载再重新挂载(比如你切换路由再回来)的时候,state才会重新初始化,这就是为什么你要切路由才生效。

下面给你几个解决办法,按推荐程度排序:

方法一:直接在render里计算(最推荐,最简单)

如果filterData这个函数的计算开销不大,完全没必要把结果存在state里。直接在render的时候计算,这样每次props更新,render都会重新执行,结果自然就即时更新了:

class Testing extends Component {
  render() {
    // 每次render时根据最新的props计算
    const filteredData = filterData(this.props.fmlProps);
    return (
      <>
        <h1>{this.props.fmlProps}</h1>
        {filteredData.map(FakeData => (
          <BookComponent key={FakeData.planNumber} PNum={FakeData.planNumber} PName={FakeData.planName} />
        ))}
      </>
    );
  }
}

这种写法省掉了维护state的麻烦,代码更简洁,还能保证数据始终是最新的。

方法二:用componentDidUpdate监听props变化

如果filterData计算开销比较大,不想每次render都执行,那可以用生命周期钩子监听props变化,只有当fmlProps真的改变时才更新state:

class Testing extends Component {
  state = {
    XXX: filterData(this.props.fmlProps)
  };

  // 组件挂载完成后初始化一次(可选,因为state已经初始化了,但如果props在挂载后才更新的话可以加)
  componentDidMount() {
    this.setState({
      XXX: filterData(this.props.fmlProps)
    });
  }

  // 当props更新时触发
  componentDidUpdate(prevProps) {
    // 对比前后props,只有变化了才更新state
    if (prevProps.fmlProps !== this.props.fmlProps) {
      this.setState({
        XXX: filterData(this.props.fmlProps)
      });
    }
  }

  render() {
    return (
      <>
        <h1>{this.props.fmlProps}</h1>
        {this.state.XXX.map(FakeData => (
          <BookComponent key={FakeData.planNumber} PNum={FakeData.planNumber} PName={FakeData.planName} />
        ))}
      </>
    );
  }
}

方法三:用getDerivedStateFromProps(复杂场景用)

如果你的组件有更复杂的state和props同步需求,可以用这个静态生命周期方法,它是专门用来处理props到state的同步的:

class Testing extends Component {
  state = {
    XXX: filterData(this.props.fmlProps),
    lastFmlProps: this.props.fmlProps // 存一下当前props,用来对比变化
  };

  // 静态方法,在render之前触发,用来根据props更新state
  static getDerivedStateFromProps(nextProps, prevState) {
    // 如果新的props和之前存的不一样,就返回新的state
    if (nextProps.fmlProps !== prevState.lastFmlProps) {
      return {
        XXX: filterData(nextProps.fmlProps),
        lastFmlProps: nextProps.fmlProps
      };
    }
    // 不需要更新state就返回null
    return null;
  }

  render() {
    return (
      <>
        <h1>{this.props.fmlProps}</h1>
        {this.state.XXX.map(FakeData => (
          <BookComponent key={FakeData.planNumber} PNum={FakeData.planNumber} PName={FakeData.planName} />
        ))}
      </>
    );
  }
}

内容的提问来源于stack exchange,提问作者adnan tariq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:54:08