gpt4 book ai didi

reactjs - 如何为具有自己状态的多个 React 组件重用相同的 Redux Saga?

转载 作者:行者123 更新时间:2023-12-03 14:32:17 25 4
gpt4 key购买 nike

解释起来有点冗长。尽可能简单:我有两个组件,EmployeesAddEmployee - 它们都附加到路由 /employeesemployees/分别添加。来自 Employee 组件的链接会将 employees/add 推送到 BrowserHistory,反之亦然(AddEmployee 组件也会推送 /employees 如果表单成功提交,或者用户单击“取消”)。

如果我导航到 /employees,该组件工作正常。如果我单击导航到 /employees/add 组件可以正常工作。如果我单击“取消”或提交表单以重定向回 /employees...该组件就会中断。

通过大量调试,我确定这是因为 AddEmployee 的 redux 状态一直持续到 Employee。我的猜测是这是因为他们都使用相同的传奇故事。我编写了一个 get Redux saga 来处理对远程 API 的请求。 Employees 显然使用 get saga 来检索所有用户,而 AddEmployee 使用 get saga 来检索可能的位置将用户分配给。

加载 Employees 时,apiGet saga 的状态包含检索到的员工。加载 AddEmployee 时,apiGet saga 的状态包含检索到的位置。然后,当您返回Employees 时,apiGet saga 的状态仍然包含检索到的位置,并且它确实不再运行来再次加载员工。

我该如何解决这个问题?

我已尽力将下面的代码压缩为相关部分。

get 传奇:

function getApi(endpoint, token) {
return fetch(apiUrl + endpoint, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
}
}).then(handleApiErrors)
.then(response => response.json())
.catch((error) => {throw error})
}

function* apiGetFlow(endpoint) {
let response, token
try {
token = localStorage.getItem('token')
token = JSON.parse(token)

response = yield call(getApi, endpoint, token)

yield put({ type: CLIENT_GET_SUCCESS, response: response })

} catch(error) {
...
}

return response
}

function* apiGetWatcher() {
while(true) {
const { endpoint } = yield take(CLIENT_GET_REQUESTING)
const task = yield fork(apiGetFlow, endpoint)
}
}

export default apiGetWatcher

Employees 组件:

class Employees extends Component {

componentDidMount() {
this.usersGet()
}

usersGet() {
this.props.apiGetRequest('users')
}

render() {
...
}
}

const mapStateToProps = state => {
return {
users: state.apiGet,
}
}

const connected = connect(mapStateToProps, { apiGetRequest })(Employees)

export default connected

AddEmployee 组件:

class AddEmployeeForm extends Component {

componentDidMount() {
this.locationsGet()
}

locationsGet() {
this.props.apiGetRequest('locations')
}

render() {
...
}
}

const mapStateToProps = state => {
return {
locations: state.apiGet,
save: state.apiPost,
}
}

const formed = reduxForm({
form: 'addemployee',
})(AddEmployeeForm)

const connected = connect(mapStateToProps, { apiGetRequest, apiPostRequest })(formed)

export default connected

最佳答案

我怀疑是因为你的 React 组件没有卸载。看起来组件是从 componentDidMount 生命周期方法内部触发其 api 请求的。

假设您从 /employees/ 开始,Employees 组件将为用户安装并分派(dispatch) api 请求。

当您导航到 /employees/add 时,AddEmployeeForm 组件会安装并分派(dispatch)位置的 api 请求。

当您按返回键并返回到 /employees 时,Employees 组件已安装。因此,它不会再次触发“用户”的请求。

您可以通过在每个组件中使用 console.log 实现 componentWillUnmount 方法来验证这是否是问题。

话虽如此,在我看来,您不应该在期望数据完全不同的组件之间共享 state.apiGet reducer 。不同的数据应该在我们的 reducer 中维护。

假设您重构了组件,以便在来回时成功分派(dispatch) API 请求,并且 state.apiGet 会相应更新。这真的是你想要的吗?每次用户按下前进和后退时,API 响应是否会有所不同?此外,API 请求会出现延迟,并且 state.apiGet 最初会得到错误的数据,直到请求完成为止。

我将创建一个users 缩减器和一个locations 缩减器。然后创建两个封装您的 getApi 方法的 sagas 并分派(dispatch)它们的特定操作。

例如:

function* getUsers(endpoint) {
let response, token
try {
token = localStorage.getItem('token')
token = JSON.parse(token)

response = yield call(getApi, endpoint, token)

yield put({ type: 'ADD_USERS', response: response })

} catch(error) {
...
}

return response
}

function* getLocations(endpoint) {
let response, token
try {
token = localStorage.getItem('token')
token = JSON.parse(token)

response = yield call(getApi, endpoint, token)

yield put({ type: 'ADD_LOCATIONS', response: response })

} catch(error) {
...
}
return response
}

在您的组件中:

const mapStateToProps = state => {
return {
users: state.users,
}
}

const mapStateToProps = state => {
return {
locations: state.locations,
save: state.apiPost,
}
}

Official Redux中有具体信息有关如何创建单独的 reducer 的文档。

关于reactjs - 如何为具有自己状态的多个 React 组件重用相同的 Redux Saga?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46329023/

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