React-redux中JSX内函数组件无法随props更新重渲染问题
问题根源:MultiChoice 组件未同步 props 更新
你遇到的问题核心在于 MultiChoice 组件将 props 数据存入 state 后,没有在 props 更新时同步更新 state。具体来说:
- 当 Redux 状态更新后,App 组件的
this.props.question确实更新了,render 方法也会重新执行,并且向 MultiChoice 传入了新的questionContentprops。 - 但 MultiChoice 的
question和answerArray状态是在 constructor 中初始化的——而 constructor 仅在组件首次挂载时执行一次。后续 props 变化时,state 不会自动同步,所以组件依然使用旧的 state 数据渲染,看起来就像没更新。
解决方案:直接使用 props 或同步 props 到 state
方案一:直接使用 props(推荐)
既然 question 和 answerArray 是从父组件传入的动态数据,完全没必要存入 state,直接使用 props 即可。仅将需要组件内部管理的状态(比如选中的答案 ID、提示信息)保留在 state 中。
修改后的 MultiChoice 代码:
import React, { Component } from 'react'; import ReactHtmlParser from 'react-html-parser'; import './questions.css'; class MultiChoice extends Component { constructor(props) { super(props); // 只保留组件内部需要管理的状态 this.state = { selectedAnswerId: null, information: null } this.buttonClick = this.buttonClick.bind(this); } // 当新问题传入时,重置内部状态 componentDidUpdate(prevProps) { if (prevProps.questionContent !== this.props.questionContent) { this.setState({ selectedAnswerId: null, information: null }); } } createButtons() { const { answers } = this.props.questionContent; const { selectedAnswerId } = this.state; return answers.map((element) => ( <span key={element._id} onClick={() => this.buttonClick(element._id)} className={`span-button-wrapper-25 ${element._id === selectedAnswerId ? "active" : ""}`} > <label> <span>{element.answer}</span> </label> </span> )); } buttonClick(id) { this.props.buttonClicked(id); // 从 props 的答案列表中找到对应提示信息 const selectedAnswer = this.props.questionContent.answers.find(ans => ans._id === id); this.setState({ selectedAnswerId: id, information: selectedAnswer?.information }); } render() { const { question } = this.props.questionContent; const { information } = this.state; return ( <div className="question-container"> <div className="question-view"> <div className="icon-row"> <i className="fa fa-code" /> </div> <div className="title-row"> {question} </div> <div className="button-row"> {this.createButtons()} </div> <div className="information-row"> {ReactHtmlParser(information)} </div> </div> </div> ); } } export default MultiChoice;
方案二:同步 props 到 state(不推荐)
如果一定要保留 state 中的 question 和 answerArray,需要在 componentDidUpdate 中监听 props 变化,手动更新 state:
componentDidUpdate(prevProps) { // 仅当 questionContent 变化时更新 state if (prevProps.questionContent !== this.props.questionContent) { this.setState({ question: this.props.questionContent.question, answerArray: this.props.questionContent.answers, information: null }); } }
这种方式多了一层状态同步,容易引发不一致问题,所以优先选择方案一。
额外验证:Redux 部分是否正确
你的 Redux 代码是没问题的:
- Reducer 每次返回新的对象(
return { question: action.payload.data, selected: false }),符合 Redux 不可变更新的要求,能触发组件 props 更新。 - App 组件的
mapStateToProps正确映射了 state,所以 props 更新能传递到子组件。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

