【发布时间】:2021-08-07 04:44:23
【问题描述】:
我在文件searchSlice.js 中定义了一个 Redux Toolkit 切片,它负责查询 API 并将响应数据存储在 store 的 state 中。目前看起来是这样的:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';
const initialState = {
query: '',
status: 'idle',
movies: [],
totalResults: null,
};
// Create slice
export const searchSlice = createSlice({
name: 'search',
initialState,
reducers: {
updateQuery: (state, action) => {
state.query = action.payload;
},
},
extraReducers: (builder) => {
builder
.addCase(getMovies.pending, (state) => {
state.status = 'pending';
})
.addCase(getMovies.fulfilled, (state, action) => {
state.status = 'idle';
state.movies = action.payload.results;
state.totalResults = action.payload.total_results;
});
},
});
// Actions
export const { updateQuery } = searchSlice.actions;
// Reducers
export default searchSlice.reducer;
// Selectors
export const selectQuery = (state) => state.search.query;
export const selectStatus = (state) => state.search.status;
export const selectAllMovies = (state) => state.search.movies;
export const selectTotalResults = (state) => state.search.totalResults;
// Thunks
export const getMovies = createAsyncThunk(
'search/getMovies',
async (payload, store) => {
if (!store.getState().search) {
dispatchEvent(updateQuery(payload));
}
try {
console.log('payload: ', payload);
const res = await axios.get(`/search?query=${store.getState().search}`);
return res.data;
} catch (err) {
return err;
}
}
);
正如我所见,除了导出实际的切片对象本身之外,您还必须导出其必要和附带的组件:
- 操作
- 减速机
- 选择器
- 谢谢
由于上述组件高度耦合和相互依赖的性质,ESLint 将根据 searchSlice.js 文件中组件的顺序(按行号)抛出不同的 linting 错误。比如上面的代码sn-p,linting的错误是:
'getMovies' was used before it was defined. eslint(no-use-before-define)
如果我们尝试通过将 getMovies 函数声明重新排列到调用上方来修复错误,如下所示:
// ...
// Thunks
export const getMovies = createAsyncThunk(
'search/getMovies',
async (payload, store) => {
if (!store.getState().search) {
dispatchEvent(updateQuery(payload));
}
try {
console.log('payload: ', payload);
const res = await axios.get(`/search?query=${store.getState().search}`);
return res.data;
} catch (err) {
return err;
}
}
);
// ...
// Create slice
export const searchSlice = createSlice({
name: 'search',
initialState,
reducers: {
updateQuery: (state, action) => {
state.query = action.payload;
},
},
extraReducers: (builder) => {
builder
.addCase(getMovies.pending, (state) => {
state.status = 'pending';
})
.addCase(getMovies.fulfilled, (state, action) => {
state.status = 'idle';
state.movies = action.payload.results;
state.totalResults = action.payload.total_results;
});
},
});
// ...
然后我们得到相同的 linting 错误,但函数定义不同:
'updateQuery' was used before it was defined. eslint(no-use-before-define)
似乎不管文件的排列方式如何,ESLint 都会抛出一个自相矛盾的no-use-before-define 错误。
是否有不涉及更改 ESLint 规则的解决方案?有没有更好的方法来构建代码?我已经尝试将其拆分为更小的文件,但由于随附切片功能的高度相互依赖性质,ESLint 将开始抛出 import/no-cycle 错误,因为两个文件都需要相互导入内容。
作为一个附加问题,提升在这里如何发挥作用?
【问题讨论】:
标签: reactjs redux eslint redux-thunk redux-toolkit