[英]React-Redux: Make api call after set state
我有一个页面,可以在其中恢复有关某些经理的信息。 当用户使用<select>
选择一个经理时,我将 ID 保存在 state 中。 现在我将使用这个 id 从另一个 api 进行另一个提取。
我的问题是,一开始经理 state 是未定义的,所以第二个 api 调用给我一个 500 错误,直到设置经理 ID。 一旦选择了管理器,就会连续调用 API(因为它已插入渲染中)。
在选择经理的 ID 后,我会找到一种方法来进行第二次 api 调用,您认为我该怎么做?
componentDidMount() {
// with this part I recover the managers' list
this.props.managerList()
}
//...
render() {
// this is the part:
let managers = this.props.managers
console.log("manager: ", managers)
let idManager = this.state.manager_id;
console.log("idManager: ", idManager)
if(typeof idManager != "undefined"){
this.props.agendaList(idManager)
}
return (
<div className = "ml-5 mr-5 mt-5">
<div>
</div>
<form onSubmit={this.handleSubmit}>
<div>
<label>Manager</label>
<div className="bootstrap-select-wrapper">
// there I save the manager_id that I pass in my second api (agendaList)
<select title="Choose Option" onChange={(e) => this.setState({ manager_id: e.target.value })}>
<option value="" title="Choose Option" data-content="Cancel <span class='reset-label'></span>"></option>
{managers && managers.length && managers.map((manager) => (
<option key={manager.id} value= {manager.id} name="manager_id" >{manager.name} {manager.surname}</option>
))}
</select>
</div>
</div>
编辑。 好的,由于您的回答,我已经编辑了代码。 现在的问题是当我 select 经理并执行议程列表(manager_id)调用时,我得到:
在我选择经理之前:
(2) [{…}, {…}]
0: {id: "12", name: "Name1", surname: "Surname1"}
1: {id: "13", name: "Name2", surname: "Surname2"
之后(所以在我调用 this.props.agendaList(manager_id)
0: {id: "12", name: "Name1", surname: "Surname1"}
1: {id: "13", name: "Name2", surname: "Surname2"}
2: {manager_id: "12", date: "2020-05-27", start_at: "09:00:00"}
3: {manager_id: "12", date: "2020-05-27", start_at: "10:00:00"}
我换了经理
(5) [{…}, {…}, {…}, {…}, {…}]
0: {id: "12", name: "Name1", surname: "Surname1"}
1: {id: "13", name: "Name2", surname: "Surname2"}
2: {manager_id: "12", date: "2020-05-27", start_at: "09:00:00"}
3: {manager_id: "12", date: "2020-05-27", start_at: "10:00:00"}
4: {manager_id: "13", date: "2020-05-28", start_at: "10:00:00"}
我会将答案与我的 api 分开。
case 'MANAGER_LIST':
return [...state, ...action.managers];
case 'AGENDA_LIST':
return [...state, ...action.agenda];
您不应该在渲染方法中进行任何 API 调用。 您可以编写一个单独的处理程序来设置 state 并进行 API 调用
handleChange = (e) => {
const manager_id = e.target.value
this.setState({ manager_id })
this.props.agendaList(manager_id)
}
render() {
let managers = this.props.managers
console.log("manager: ", managers)
let idManager = this.state.manager_id;
console.log("idManager: ", idManager)
return (
<div className = "ml-5 mr-5 mt-5">
{/* Other code */>}
<select title="Choose Option" onChange={this.handleChange}>
<option value="" title="Choose Option" data-content="Cancel <span class='reset-label'></span>"></option>
{managers && managers.length && managers.map((manager) => (
<option key={manager.id} value= {manager.id} name="manager_id" >{manager.name} {manager.surname}</option>
))}
</select>
{/*other code*/}
</div>
)
}
编辑:根据您编辑的帖子,您似乎希望数据是分开的。 为此,您需要将它们分别存储在减速器中
const reducer = (state = {managers: [], agents: []}, action) => {
case 'MANAGER_LIST':
return {...state, managers: [...state.managers, ...action.managers]};
case 'AGENDA_LIST':
return {...state, managers: [...state.managers, ...action.agenda]};
}
发布您也需要更新 mapStateToProps
const mapStateToProps = (state) => {
return {
managers: state.managers,
agenda: state.agenda,
}
}
您可以将第二个 api 调用包装在 if state 中,以便仅在管理器 state 未定义时执行。 并且您的 onChange 应该链接到外部渲染的 function ,这并不重要,但很好的做法。
不要在 state 中设置选定的 ID。 在 select 上,可以直接调用 redux 动作。 例如,
这将在经理下拉 select 上调用,
onMangerSelect(selectedId) {
this.props.getManagerDetails(selectedId);
}
这将调用 redux 动作,
const mapDispatchToProps = dispatch => {
return {
getManagerDetails : (managerId) => {
dispatch(getDataFromManagerAPI(managerId));
}
};
};
好吧,React 是关于……反应性的。 使用 React 时,一个好的心态是始终对变化做出反应。
在我看来,可以像从组件中选择一个值时那样更改 state (*尽管我会写一个处理 function ,就像第一个答案一样,为了更清晰和更有条理的代码)。
您需要做的是确保有一段代码知道如何对该更改做出反应 -> 在我们的例子中,进行 API 调用。 一个示例解决方案可能是:
componentDidMount() {
// with this part I recover the managers' list
this.props.managerList()
}
componentDidUpdate(prevProps, prevState) {
// Whenever the component updates we'll check what changed and react
// accordingly
this.handleNewManagerSelection(prevState);
}
handleNewManagerSelection(prevState) {
const { manager_id } = this.state;
// This means we have a new manager id in our state so we need
// to run our agendaList API call
if (prevState.manager_id !== manager_id) {
this.props.agendaList(manager_id);
}
}
render() {
// this is the part:
let managers = this.props.managers
console.log("manager: ", managers)
let idManager = this.state.manager_id;
console.log("idManager: ", idManager)
if(typeof idManager != "undefined"){
this.props.agendaList(idManager)
}
return (
<div className = "ml-5 mr-5 mt-5">
<div>
</div>
<form onSubmit={this.handleSubmit}>
<div>
<label>Manager</label>
<div className="bootstrap-select-wrapper">
// there I save the manager_id that I pass in my second api (agendaList)
<select title="Choose Option" onChange={(e) => this.setState({ manager_id: e.target.value })}>
<option value="" title="Choose Option" data-content="Cancel <span class='reset-label'></span>"></option>
{managers && managers.length && managers.map((manager) => (
<option key={manager.id} value= {manager.id} name="manager_id" >{manager.name} {manager.surname}</option>
))}
</select>
</div>
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.