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

如果连接到未更改的存储,则React componentDidUpdate方法不会在继承的道具更改上激发

裴和怡
2023-03-14

我想知道我的组件是否已经加载了一些库。要知道,从任何上下文,我把它连接到我商店的“库”减速器到我的组件。我还从调用组件的父级传递一个配置对象this.props.dataObject。像这样:

class GoogleButton extends Component {
    render() {
        if (this.props.libraries.google) {
            return <a id='sharePost' className='google_icon'></a>
        } else {
            return null
        }
    }

    componentDidUpdate() {
        gapi.interactivepost.render('sharePost', this.props.dataObject)
    }
}

function mapStateToProps(state) {
    return { libraries: state.libraries }
}

export default connect(mapStateToProps)(GoogleButton)

处理库状态的reducer如下所示:

let newState = {...state}
newState[action.libraryName] = action.state
return newState 

当我更改库状态时,componentDidUpdate起作用。问题是当我更改父级继承的道具时this。道具。数据对象。在这种情况下,componentDidUpdate不会触发。如果我从组件中移除connect,它将按要求工作。我错过了什么?

共有3个答案

皮弘博
2023-03-14

我也有同样的问题,我使用了object。分配用于创建新状态,但我使用combineReducer,它会导致多级状态,在我的情况下,我将整个状态作为道具传递给组件,因此浅层相等性检查无法检测到我的状态更改,所以componentDidUpdate没有调用,在我的情况下,使用combine reducer时,在级别中传递状态更改是很重要的

const MapStateToProps=(state)=>{
    return {
        reportConfig:state.ReportReducer
    }
};

而我的州树是这样的

  {
  ReportReducer: {
    reportConfig: {
      reportDateFilter: 'this week',
      reportType: null,
      reportShopId: null,
      updateShop: true
    }
  }
}

在我的reducer中,以如下方式返回它作为ReportReducer

export default combineReducers({reportConfig});

我的根部减压器是这样的

const rootReducer =combineReducers({ReportReducer});

const store = createStore(rootReducer ,{},enhancer);
爱琪
2023-03-14

我解决了。我不能100%确定这是准确的,但我会解释的。如果我做错了什么,请纠正我。

我一直在想丹在回答中说的肤浅的平等检查。问题就在那里。我从父对象传递了一个对象,该对象的嵌套元素就是更改的元素。对象保持不变。因此,使用connect带来的浅相等检查,组件将永远不会更新。

我的解决方案是在父使用Object.assign({},dataObject)当我传递道具时,所以我制作了另一个不同的对象。现在浅平等检查可以比较它,并确定道具已经改变,在更新组件之前。

丘智志
2023-03-14

很可能你的一些道具在组件之外发生了变异
例如,您可能会呈现如下组件:

class Parent extends Component {
  constructor() {
    super()
    this.state = { libraries: {} }
  }

  handleClick() {
    // MUTATION!
    this.state.libraries.google = true

    // Normally this forces to update component anyway,
    // but React Redux will assume you never mutate
    // for performance reasons.

    this.setState({ libraries: this.state.libraries })
  }

  render() {
    return (
      <div onClick={() => this.handleClick()}>
        <GoogleButton libraries={this.state.libraries} />
      </div>
    )
  }
}

由于Redux应用程序处理不可变数据,connect()对其道具使用浅层相等检查,以避免不必要的重新渲染。然而,如果你在应用程序中使用变异,这将不起作用。

你有两个选择:

这是最好的选择。例如,而不是像

  handleClick() {
    this.state.libraries.google = true
    this.setState({ libraries: this.state.libraries })
  }

你可以写

  handleClick() {
    this.setState({
      libraries: {
        ...this.state.libraries,
        google: true
      }
    })
  }

这样我们就创建了一个新对象,这样connect()就不会忽略已更改的引用。(我在这段代码中使用的是对象扩展语法。)

更糟糕的选择是完全禁用由connect()进行的性能优化。然后,即使你在父级中对道具进行了变异,你的道具也会更新,但你的应用程序会变慢。要执行此操作,请更换

export default connect(mapStateToProps)(GoogleButton)

具有

export default connect(mapStateToProps, null, null, { pure: false })(GoogleButton)

除非绝对必要,否则不要这样做。

 类似资料:
  • 问题内容: 我想让我的组件知道是否已经加载了一些库。要知道从任何上下文来看,我都将其连接到商店的“库” reduce组件中。我还从调用组件的父级那里传递了一个配置对象。像这样: 处理库状态的reducer如下所示: 当我更改库状态时有效。问题是当我改变父母继承的道具时。在这种情况下,componentDidUpdate不会触发。如果我从组件中删除,它会按预期工作。我在这里想念什么吗? 问题答案:

  • 问题内容: 是否可以在sql中执行更新语句,但仅在更新不同时才执行更新? 例如 如果在数据库中, 不应 执行任何类型的更新 但是,如果 这 应该 执行更新。 问题答案: 使用更新前触发器可以做到这一点。在此触发器中,您可以将旧值与新值进行比较,并在新值不变的情况下取消更新。但这将导致呼叫者网站上的错误。 我不知道为什么要这样做,但是这里有几种可能性: 性能:这里没有性能提升,因为更新不仅需要找到正

  • 我有以下结构: ChildComponent只是呈现值:

  • 我想使用JavaFX ListView控件显示一个人员列表(在POJOS中编码,包含一个name和surname属性)。我创建了ListView,并将persons列表添加为ObservableList。如果我在ObservableList中删除或添加一个新人,那么一切都可以正常工作,但是POJO中的更改不会触发ListView的更新。我必须从ObservableList中移除和添加修改后的POJ

  • 所以我对vue的父子组件通信有问题。问题是,当我导航到一个组件后,它应该调用ajax从服务器获取数据。收到数据后,父组件应该通过道具将其发送给所有子组件,但道具数据不显示。子组件只有在我更改编辑器上的代码后才开始显示props数据。这是我父组件的代码 这是我的单一产品规格组件,不会加载道具数据: 正如我所说,我的单一产品规范组件的唯一问题不是它不会加载道具数据。问题是,当我在文本编辑器中更改代码时

  • 以下是我需要更改的一些值: 如果第一列是2= 如果第一列是8= 如果第一列是16= 然而,这个命令并不方便,因为它改变了缩进,并且带有8的行似乎不适合: 输出: 您将如何更正更通用的内容(这意味着即使特定行的缩进不同,它也可以工作),并且不会改变原始文件的缩进?