当前位置: 首页 > 知识库问答 >
问题:

组件在状态更改后不会重新渲染

刘升
2023-03-14

我有一个带有两组按钮(功能和目标)的界面。当我点击一个按钮时,我希望它从一个团队转到另一个团队。我正在用react和redux实现这一点。我唯一的问题是,当状态更新并且我成功地记录了更新的状态时,除非我使用forceUpdate(),否则组件不会更新。我不明白的是,既然状态更新成功,组件不应该自动重新渲染吗?

一些js

class Some extends React.Component{

    constructor(props){
        super(props)
        this.state = {
            selectedFeatures:[],
            selectedTargets:[]
        }
    }

    setStateFromProps(){
        this.setState({
            selectedFeatures: this.props.features,
            selectedTargets: this.props.targets,
        }, console.log(this.state.selectedFeatures, this.state.selectedTargets))
    }

    componentDidMount(){
        this.setStateFromProps()
    }

    render(){

        const { features, targets} = this.props

        const updateLists =(selectedFeature, flag) =>{
            let index
            if  (flag){
                index = features.indexOf(selectedFeature)
                features.splice(index, 1);

                targets.push(selectedFeature)

                this.props.addFeature({features, targets})
            }else{
                index = targets.indexOf(selectedFeature)
                targets.splice(index, 1);

                features.push(selectedFeature)
                this.props.addFeature({targets, features})
            }

            console.log(this.state.selectedFeatures, this.state.selectedTargets)


        }

        return (
            <div>
                {this.state.selectedFeatures.map(feature => {

                    return <div><button key={feature} onClick={() => updateLists(feature, true)}>{feature}</button> <br /></div>
                })}
                <br />
                {this.state.selectedTargets.map(target => {
                    return <div><button key={target} onClick={() =>updateLists(target, false)} >{target}</button> <br /></div>
                })}
            </div>
        );

    }
}

const mapDispatchToProps =(dispatch) =>{
    return {
            addFeature: (data) => dispatch(featureAddedToTargets(data)),
        }
} 
const mapStateToProps= (state)=>{
    return { selectedFeature:state.addFeatureReducer.selectedFeature,
            features: state.addFeatureReducer.features,
            targets: state.addFeatureReducer.targets
    };
}


export default connect(mapStateToProps, mapDispatchToProps)(Some);

正如您所看到的,当我单击一个按钮时,我触发updateLists函数,该函数将使计算更改为发送到我们的唯一操作带有更新的功能和目标按钮的新数据,该操作将更改reducer中的状态。

添加目标动作

    export const featureAddedToTargets = (data) =>{
        return {
            type: FEATURE_CHANGED,
            data
        }
    }

附加特性减速器

    const initialState = {
        features:['f1','f2','f3','f4','f5'],
        targets:['t1','t2']
    }

    const addFeatureReducer = (state=initialState, action) =>{
        switch(action.type){
            case FEATURE_CHANGED:
                console.log("action: ", action)
                return {...state , state, features: action.data.features, targets: action.data.targets};
            default: 
                return state;
        }
    }
export default combineReducers({ addFeatureReducer })

正如我所说的,尽管reducer中的初始状态发生了变化,因此某些组件中的道具也发生了变化,但Some组件不会重新渲染,按钮组保持不变。我想知道为什么会这样。

在此输入图像描述

共有3个答案

家经纶
2023-03-14
setStateFromProps(){
        this.setState({
            selectedFeatures: this.props.features,
            selectedTargets: this.props.targets,
        }, console.log(this.state.selectedFeatures, this.state.selectedTargets))
    }

尝试将此更改为

    componentDidUpdate(prevProps) {
        if(this.props.features !== prevProps.features || this.props.targets !== prevProps.targets) {
      this.setState({
            selectedFeatures: this.props.features,
            selectedTargets: this.props.targets,
        }, console.log(this.state.selectedFeatures, this.state.selectedTargets))
    }

}
太叔京
2023-03-14

启动动作功能\u CHANGED后,减速器将返回一个更新的状态,该状态将通过mapStateToProps作为newProps传播到React组件。在render函数中,您将映射到上。状态所选功能此。状态所选目标。从我看到的情况来看,虽然您获得了新的道具功能目标,但您并没有在组件的状态下更新它们。您可以使用getDerivedStateFromPropslifecycle在新道具到达时更新状态。

getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.features !== prevState.features && nextProps.targets !== prevState.targets) {
        return ({
           selectedFeatures: nextProps.features,
           selectedTargets: nextProps.targets
        });
    }
    else if (nextProps.features !== prevState.features) {
       return ({
           selectedFeatures: nextProps.features,
        });
    } else if (nextProps.targets !== prevState.targets) {
       return ({
           selectedTargets: nextProps.targets,
        });
    }
}

你可以在这里查阅:https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

丁子石
2023-03-14

所以我明白了为什么即使状态在更新,组件也没有更新。似乎在updatedLists()中,我直接在redux存储的功能和目标数组上使用了push()和splice(),从而改变了我的状态。由于变异,该组件在当前和下一个状态中没有看到变化。React在内存中保留状态的两个版本—当前版本和下一个版本。它比较两者并仅使用已更改的部分更新DOM。由于我改变了状态,React将当前和下一个视为相同,因此没有更新。所以我刚刚更改了updatedLists(),我在随机变量(特性和目标)中应用了push()和splice(),之后我将它们作为数据传递给我们的操作,并使用spread操作符(正如我们之前所做的)将它们的值传递到存储的状态(initialState)。

if  (flag){
            index = this.state.selectedFeatures.indexOf(selectedFeature)
            const Features = [...this.state.selectedFeatures]
            Features.splice(index, 1);

            const Targets = [...this.state.selectedTargets]
            Targets.push(selectedFeature)

            console.log('features',features,'targets',targets)
            this.props.addFeature({features: Features , targets: Targets})
        }else{
            index = this.state.selectedTargets.indexOf(selectedFeature)
            const Targets = [...this.state.selectedTargets]
            Targets.splice(index, 1);

            const Features = [...this.state.selectedFeatures]
            Features.push(selectedFeature)

            console.log('features',features,'targets',targets)
            this.props.addFeature({ features:Features, targets: Targets})
        }
 类似资料:
  • 我有一个基于url的react组件,它应该导入一些数据,然后在另一个子组件中显示。当页面首次加载时,它将初始数据作为组件状态加载到中。至于进一步的url更改,它们将在export default class Info()中处理。组成部分{ 我的问题是,尽管switch语句中有状态更新,但组件不会重新渲染。我不知道我的方法有什么问题。有人能帮我吗?谢谢 编辑:这是使用而不是的代码:

  • 问题内容: 我从React中学到的一件事是,如果组件的属性不变,那么React不会重新渲染组件。无状态组件也是如此吗?还是它们的行为更像“愚蠢的”函数,并且每次都会执行? 例如,如果我有: 当更新其价值,并获取重新渲染?还是像其他React组件一样足够“聪明”地看到其道具没有改变? 问题答案: 更新25.10.2018 从React 16.6开始,您可以将React.memo用于功能组件以防止重新

  • 这个问题在这里已经得到了回答,但事情总是在变化。 基本上,父组件获取一些数据,子组件需要这些数据。 这是子组件。

  • 有一个案例我很困惑。 我有一个对象redux状态:{show:true,creative:{name:'a',tags:[t1,t2,t3]}。此对象已通过“react redux”的“connect”功能映射到道具。 当我改变属性“显示”或“creative.name”时,它确实会触发重新渲染。但是如果我将t0追加到"creative.tags",它就不会运行re-渲染。 我必须分配一个新变量来

  • 我正在学习如何应对,我整天都在试图找到解决问题的办法,但都没有成功。然后决定在这里提出我的第一个问题。 我有子组件,包括React-Datepicker组件和单独的“第二天”和“前一天”按钮来更改选定的日期。 SelectedDate存储在父组件的状态中。 我试图从子组件更新父组件的状态,当状态更新时,子组件应该重新呈现,因为该状态作为道具传递给同一个子组件。 我已设法从child更改父状态,但子

  • 我在一个应用程序的前端原型上工作,该应用程序具有给定的JS、React和CoreUI4 React技术栈。我来自Python背景,在网络开发和我给定的技术堆栈方面没有太多经验。当我不得不开始使用钩子时,这一点变得很明显。 问题 我真的不明白为什么它不更新我的和/或不渲染。我需要一个条件渲染,我也使用。 我试图: 从我的主应用程序中传递一个更大的状态,一旦我启动条件逻辑(挂钩规则)就无法工作。 当我