如何在其他组件的状态更改时重新渲染 DOM

Posted

技术标签:

【中文标题】如何在其他组件的状态更改时重新渲染 DOM【英文标题】:how to rerender DOM on state change by other component 【发布时间】:2017-08-10 18:54:12 【问题描述】:

我看到了这个post,但不知道如何在我的情况下申请。基本上我有 3-4 个输入范围栏,如果用户更改任何滑块,其他 2/3 滑块会自动更改。我从后端获得的初始值。之后,我为我的状态添加了初始值。为此,我编写了这样的代码

我的父组件

 constructor(props)
       super(props);
       this.state =
           objectiveData:[]
       
        var objectiveData = this.state;
        this.props.objective_value.map((data,index) =>

             var newObj =;
            newObj['url'] = data.url;
            newObj['name'] = data.name;
            newObj['value'] = data.value;
            newObj['pk'] = data.pk;
            objectiveData[index] = newObj;
        )
        console.log("lcal",objectiveData)
        this.setState(objectiveData);

updateValue = (obj) =>
        var objectiveData = this.state;
       var selectedData = objectiveData.filter((data) => data.pk === obj.pk);

        var diff=obj.value - selectedData[0].value;

        var otherData = objectiveData.filter((data) => data.pk !== obj.pk);

        var sum = otherData.map((data) =>( data.value)).reduce((a,b) => a + b,0);
        console.log("sum",sum);
        if(diff > 0)
            for(var i=0;i < objectiveData.length;i++)
                if(objectiveData[i].pk !== obj.pk)
                    console.log("object before value",objectiveData[i].value)
                    objectiveData[i].value = objectiveData[i].value - (objectiveData[i].value/sum);
                    console.log("object after value",objectiveData[i].value)
                else
                    objectiveData[i].value = obj.value;
                
            
        else if(diff <0)
            for(var i=0;i < objectiveData.length;i++)
                if(objectiveData[i].pk !== obj.pk)
                    console.log("object before value plus",objectiveData[i].value)
                    objectiveData[i].value = objectiveData[i].value + (objectiveData[i].value/sum);
                    console.log("object before value minus",objectiveData[i].value)
                else
                    objectiveData[i].value = obj.value;
                
            
        
       return this.setState(objectiveData);


 <MyInputRange maxValue=1 minValue=0 step=0.01 
               updateProgramObjectiveValue=(value) => this.props.updateProgramObjectiveValue(value)
               value=data.value objective_name=data.objective_name 
            value_type=data.value_type url=data.url pk=data.pk
            updateValueLocally=this.updateValue.bind(this)/>

这是我的子组件

updateObjectiveValues = (value) =>
this.props.updateValueLocally("value":value,"pk":this.props.pk)
  

    render()

        return(
             <InputRange
                    maxValue=this.props.maxValue
                    minValue=this.props.minValue
                    step=this.props.step
                    value=this.state.value
                    onChange=this.updateObjectiveValues.bind(this)

                   />
        )
    

但是我的滑块没有移动任何地方,即使是滑块用户移动了。所以请告诉我应该如何告诉 react 重新渲染我的组件?每当 setState 调用时,基本上反应应该重新渲染。所以我在这里破坏了什么? 编辑1: 根据克里斯的回答,我是这样添加的

 this.setState(objectiveData);
        this.forceUpdate();

但是没有运气..我错过了什么吗?

【问题讨论】:

你在渲染方法中是否使用了父组件状态?我没有看到它被使用。 【参考方案1】:

所以通常这类问题是为什么像 Redux 这样的工具存在以巩固组件之间的统一状态,因此不仅组件内的 DOM,而且组件本身都会对状态变化做出反应。如果不这样做......您需要自己设置自定义事件并触发另一个组件应该监听的事件以对该事件做出反应。

要创建和触发事件,请查看...https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

您也可以使用 forceUpdate 强制组件更新。

component.forceUpdate(callback)

默认情况下,当你的组件状态或道具改变时,你的 组件将重新渲染。如果你的 render() 方法依赖于一些 其他数据,你可以告诉 React 组件需要重新渲染 通过调用 forceUpdate()。

调用 forceUpdate() 将导致 render() 在 组件,跳过 shouldComponentUpdate()。这将触发 子组件的正常生命周期方法,包括 每个孩子的 shouldComponentUpdate() 方法。 React 仍然只会 如果标记发生变化,则更新 DOM。

通常你应该尽量避免使用 forceUpdate() 并且只 从 render() 中的 this.props 和 this.state 中读取。

https://facebook.github.io/react/docs/react-component.html#forceupdate

【讨论】:

你能解释一下我的情况该怎么做吗?

以上是关于如何在其他组件的状态更改时重新渲染 DOM的主要内容,如果未能解决你的问题,请参考以下文章

如何在状态更改(父)reactjs时重新渲染子组件

属性更改时如何重新渲染反应组件

React 子组件不会在其状态更改时重新渲染

state 用作组件中的 props,状态更改不会重新渲染组件

如何使用 react-router-dom 卸载路由更改上的组件而不是重新渲染 [重复]

setState 更改状态但不重新渲染