使用 ReactJS + Redux 时需要 componentWillReceiveProps 和 replaceProps 吗?
Posted
技术标签:
【中文标题】使用 ReactJS + Redux 时需要 componentWillReceiveProps 和 replaceProps 吗?【英文标题】:Do I need componentWillReceiveProps and replaceProps when using ReactJS + Redux? 【发布时间】:2016-08-27 08:38:48 【问题描述】:我正在与 react 一起学习 redux,并做了第一个应用程序来捕捉来自 Destiny 的一些信息并呈现给用户。该应用程序有一个选择框,用户可以在其中选择众多活动之一,然后我保存该活动以使用 ActivityComponent 上的 API 检查,问题是,我这样做了(使用 redux 获取活动标识符并保存在商店中)然后稍后我必须检索 ActivityComponent 但不知何故我必须实现这个:
componentWillReceiveProps(nextProps)
this.props = ;
this.replaceProps(nextProps, cb => this.getAjax());
replaceProps(props, callback)
this.props = Object.assign(, this.props, props);
this.setState(initialState);
callback();
如果有人可以帮助我,这是我在 github 上的存储库:https://github.com/persocon/destiny-weekly
【问题讨论】:
【参考方案1】:所以快速回答是否定的,没有必要。为什么 ?好吧,你还没有真正使用 redux。如果您查看您在替换道具 getAjax 中所做的 ajax 调用,我在您的代码库中检查了它,并看到您在收到请求后在组件中调用 setState。
使用 redux,您宁愿使用 action 和 reducer。收到该数据后,将处理该操作,调用 api,并使用 reducer 在 redux“存储”中设置状态。
好的,一个完整的示例如下所示,只需先添加redux-thunk,它肯定会帮助您继续前进,请务必阅读自述文件中的示例以更好地了解方法和原因。
function startLoading()
return
type: 'LOADING_STARTED',
isLoading: true
function doneLoading()
return
type: 'LOADING_ENDED',
isLoading: false
function setActivity(result)
let lastGist = result[0];
let activity =
identifier: result.display.identifier,
title: (result.display.hasOwnProperty('advisorTypeCategory'))? result.display.advisorTypeCategory : '',
name: (result.hasOwnProperty('details') && result.details.hasOwnProperty('activityName')) ? result.details.activityName : '',
desc: (result.hasOwnProperty('details') && result.details.hasOwnProperty('activityDescription')) ? result.details.activityDescription : '',
backgroundImg: (result.display.hasOwnProperty('image')) ? 'http://bungie.net' + result.display.image : '',
modifiers: (result.hasOwnProperty('extended') && result.extended.hasOwnProperty('skullCategories')) ? result.extended.skullCategories : [],
bosses: (result.hasOwnProperty('bosses')) ? result.bosses : [],
items: (result.hasOwnProperty('items') && result.display.identifier == "xur") ? result.items : [],
bounties: (result.hasOwnProperty('bounties')) ? result.bounties : []
return
type: 'SET_ACTIVITY',
activity: activity
export function findActivity(activity_id)
return dispatch =>
dispatch(startLoading())
$.get(activity_id, (result)=>
dispatch(doneLoading())
if(response.status == 200)
dispatch(setActivity(response.json))
else
dispatch(errorHere)
)
所以一开始它可能看起来有点吓人,但经过一两次之后,用这种方式做事会感觉更自然,而不是在组件中。
【讨论】:
所以当我在我的选择上触发 changeApiUrl 时,我实际上应该获取标识符并立即调用 ajax 并将结果放入 redux 存储中? ;o 是的,我会尝试在 github 上添加一个基于您的 src 的代码示例 :) 酷!我非常感谢那个兄弟 是的,完全令人生畏,另一个问题,你告诉我使用这个 redux-thunk,没有这个就不可能存在 $.get 之后的调度?【参考方案2】:应该不需要 replaceProps,因为 props 会自动更新。 componentWillReceiveProps 让您有机会了解此生命周期中会发生什么。
注意:你不应该破坏this.props
,因为它在内部使用。
我建议将 this.props 与 componentWillReceiveProps 中的 nextProps 进行比较,以查看所选 Activity 是否已更改。如果是这样,则触发 ajax 调用(我建议使用传递给组件的 redux 操作)。
【讨论】:
【参考方案3】:是的,我搞砸了评论哈哈抱歉,在 SelectContainer.jsx 上,现在我这样做是为了在选择更改后检索活动 json:
const mapDispatchToProps = (dispatch) =>
return
onSelectChange: (activity) =>
dispatch(changeApiUrl(activity));
dispatch(findActivity(activity));
更新
import connect from 'react-redux';
import changeApiUrl, findActivity from '../actions/index.jsx';
import ActivityComponent from '../components/ActivityComponent.jsx';
const mapStateToProps = (state) =>
return state.activity;
export class ActivityContainer extends ActivityComponent
componentDidMount()
const dispatch, identifier = this.props;
dispatch(findActivity(identifier));
export default connect(mapStateToProps)(ActivityContainer);
【讨论】:
【参考方案4】:一般来说,与 redux 反应的方法的生命周期。你应该使用 redux 方法。除非你必须在反应生命周期方法中使用。
【讨论】:
以上是关于使用 ReactJS + Redux 时需要 componentWillReceiveProps 和 replaceProps 吗?的主要内容,如果未能解决你的问题,请参考以下文章
采用reactjs 开发时,redux 和 react-route 是怎么配合使用的
键入 Redux Reactjs 时 TextField 失去焦点