gpt4 book ai didi

reactjs - 修改 redux 存储时组件不更新

转载 作者:行者123 更新时间:2023-12-03 13:35:05 26 4
gpt4 key购买 nike

我正在使用 redux thunk 返回对操作的 API 调用:

export const getActiveCampaigns = () => {
return (dispatch, getState) => {
const bearer = 'Bearer ' + getState().login.bearer
return axios.get(API.path + 'campaign/active/?website_id=' + getState().selectedWebsite.selectedWebsite + '&' + API.beaconAPI_client, { headers: { 'Authorization': bearer } })
.then(function (response) {
dispatch({
type: GET_ACTIVE_CAMPAIGNS,
activeCampaigns: response.data.response
})
})
}
}

这成功地返回了一个营销事件列表,我使用以下方法将其渲染到另一个组件中:

class ActiveCampaignsDropdown extends Component {
// usual stuff

componentDidMount(){
this.props.dispatch(getActiveCampaigns())
}

// render function displays campaigns using this.props.activeCampaigns
}

const mapStateToProps = (state) => {
return {
activeCampaigns: state.activeCampaigns.activeCampaigns
}
}

但是,请注意该操作的 getState.selectedWebsite.selectedWebsite。这是通过应用程序中其他位置的操作设置的,用户可以从下拉列表中选择一个网站。我的 reducer 如下所示:

export default function (state = {}, action) {
switch(action.type){
case SET_SELECTED_WEBSITE:
return {
...state,
selectedWebsite: action.websiteId
}
default:
return state;
}
}

export default function (state = {}, action) {
switch(action.type){
case GET_ACTIVE_CAMPAIGNS:
return {
...state,
activeCampaigns: action.activeCampaigns
}
default:
return state;
}
}

我设置所选网站的操作:

export const setSelectedWebsite = (websiteId) => {
return {
type: SET_SELECTED_WEBSITE,
websiteId
}
}

这与其他 reducer 相结合,如下所示:

export default combineReducers({
login,
activeWebsites,
activeCampaigns,
selectedWebsite
})

问题

事件事件下拉框的内容在页面加载时工作正常 - 并且状态树确实更新 - 但当所选网站发生更改时它不会更新。据我所知:

  1. 我正确地调度了操作
  2. 我正在更新状态,而不是改变它

我对 Redux 在这种情况下不能“正常工作”感到非常失望,尽管我可能因为只睡了几个小时而忽略了一些愚蠢的事情!任何帮助表示赞赏。

最佳答案

在 React 中,当发生以下三种情况之一时,组件就会更新:

  • Prop 已更改
  • 状态已更改
  • 调用forceUpdate()

根据您的情况,您希望更新 ActiveCampaignsDropdownstate.activeCampaigns商店的变化。为此,您必须连接组件,以便它接收此值作为 prop(从而在更改时强制更新)。

这可以按如下方式完成:

import {connect} from 'react-redux'

class ActiveCampaignsDropdown extends React.Component { ... }
const mapStateToProps = (state) => ({activeCampaigns: state.activeCampaigns});
const Container = connect(mapStateToProps)(ActiveCampaignsDropdown);

export default Container;

决赛Container组件将完成连接 ActiveCampaignsDropdown 的所有工作通过其 props 获得所需的存储状态。

Redux 的 connect()还允许我们连接调度函数来修改存储中的数据。例如:

// ... component declaration
// ... mapStateToProps

const mapDispatchToProps = (dispatch) =>
{
return {
getActiveCampaigns: () => dispatch(getActiveCampaigns())
};
}

const Container = connect(mapStateToProps, mapDispatchToProps)(ActiveCampaignsDropdown);

定义映射函数后,将创建容器组件并渲染容器,ActiveCampaignsDropdown将正确连接。在我的示例中,它将接收“activeCampaigns”和“getActiveCampaigns”作为 Prop ,并在它们的值发生变化时进行相应更新。

<小时/>

编辑:

再次查看您的代码后,我认为您的问题是由于没有满足更新 ActiveCampaignsDropdown 的条件造成的。当网站发生变化时。通过调用getActiveCampaigns()从您的 WebsiteDropdown (根据您的评论),这正在强制 state.activeCampaigns更改,成功更新 ActiveCampaignsDropdown 。正如我的评论中提到的,“强制”不负责这样做的组件进行此更改将被视为不好的做法。

一个完全合理的解决方案是 ActiveCampaignsDropdown “监听”当前网站的更改并相应地进行 self 更新。为此,您需要做两件事:

(1) 将网站状态映射到组件

const mapStateToProps = (state) => {
return {
activeCampaigns: state.activeCampaigns.activeCampaigns, // unsure why structured like this
selectedWebsite: state.selectedWebsite.selectedWebsite
}
}

(2) 将您的调度调用移至 componentWillReceiveProps

class ActiveCampaignsDropdown extends React.Component
{
// ...

componentWillReceiveProps(nextProps)
{
if (this.props.selectedWebsite !== nextProps.selectedWebsite)
{
this.props.getActiveCampaigns();
}
}
}

现在,每次选定的网站发生更改时,都会发生刷新,并且 componentWillReceiveProps()将被调用(导致 activeCampaigns 也更新)。应用此更新后,将发生另一次刷新,并且呈现的下拉列表将包含新更新的广告系列。

一些小的改进:

  • 如果您的许多组件依赖于当前网站的状态(我想有很多),那么您可以考虑通过 context 向它们提供它.

  • 现在你的ActiveCampaignsDropdown接收 'selectedWebsite' 作为 prop,您可以将其直接传递给您的操作函数,而不是让它从状态中获取它(使用 getState() ) - 顺便说一下,如果可能的话,也应该避免这种情况。

关于reactjs - 修改 redux 存储时组件不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49064590/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com