侧边栏的请求
期望结果:
输入值之后 点击apply可以完整地将输入值拼贴到请求路径中
问题:
拼贴到请求路径的值总是比实际输入的值少一位(慢一位)
背景:
真正发送网络不是在这个组件,而是在外层filter页面,用了dispatch将输入值minValue和maxValue传递给外层filter页面,filter页面useEffect监听,变化了就去发送请求
解决过程:
是dispatch出了问题吗?使用到的数据总是少一位 可能是没有及时dispatch,看handleMinMaxInput是怎么将值存储起来的,结果确实是这个函数的问题
const handleMinMaxInput = (value: number, valueType: string) => {
console.log("value", value)
// 这里clg还是对的
console.log("valueType", valueType)
if (valueType == 'min') {
dispatch(setVolumeMin({ volume_min: value }));
setMinValue(value);
setIsMin(true)
} else if (valueType == 'max') {
console.log("1015", valueType, value)//这里也是对的
dispatch(setVolumeMax({ volume_max: value }))//在这里就去dispatch 因为后面set会异步 然后再去取值diapatch会慢一步
setMaxValue(value);
setIsMax(true)
}
// 从这里开始就慢了
console.log("volume_max", maxValue)
// 不要在这里再去dispatch
// valueType == 'max' && dispatch(setVolumeMax({ volume_max: maxValue }));
}
这个功能模块在其他地方也有用到 当时卡很久,一直没有拿到实时正确的输入值给到请求路径,就先做其他模块,其他模块也用到这个功能,遇到了一样的问题, 逃不掉😶
而且用户如果只是输入min没有输入max这样子max是undefined,发送请求拼贴了undefined会没有结果,所以不能将undefined,NaN的值拼贴进去:
!isNaN(volume_min) &&
volume_min &&
params.push("volume_min=" + volume_min);
在真正发送请求的时候也有问题:
数据没有及时更新到请求中,我在filter页面已经能实时拿到正确的输入值了,但是请求路径有问题,后面发现是 setParamsArray((prevParamsArray) => [...params]); react setState异步导致的
useEffect(() => {
console.log("1031end_date_min", end_date_min);//已经能实时拿到正确的输入值了
console.log("1031end_date_max", end_date_max);
setList([]);
if (allTabsVisible) {
console.log("1031endcategory_ids", category_ids?.length !== 0);
category_ids?.length !== 0 &&
category_ids &&
params.push("category_ids=" + category_ids.category_ids.join(","));
!isNaN(volume_min) &&
volume_min &&
params.push("volume_min=" + volume_min);
!isNaN(volume_max) &&
volume_max &&
params.push("volume_max=" + volume_max);
!isNaN(liquidity_min) &&
liquidity_min &&
params.push("liquidity_min=" + liquidity_min);
!isNaN(liquidity_max) &&
liquidity_max &&
params.push("liquidity_max=" + liquidity_max);
end_date_min !== "" &&
end_date_min &&
params.push("end_date_min=" + end_date_min);
end_date_max !== "" &&
end_date_max &&
params.push("end_date_max=" + end_date_max);
//mark isNaN(null) = false
is_closed !== undefined &&
is_closed !== null &&
params.push("is_closed=" + is_closed);
featured !== null && params.push("featured=" + featured);
page !== undefined && params.push("page=" + 1);
setIsTemplist(true);
search && params.push("group_name=" + encodeURIComponent(search));
console.log("1031endparams", params);
} else {
// 模块的保存值在clear all后也要清除
dispatch(resetValue());
dispatch(resetLiquidityValue());
dispatch(resetStatusValue());
dispatch(resetEndDateValue());
dispatch(resetSearchValue());
dispatch(resetCategoryIdValue());
}
setParamsArray((prevParamsArray) => [...params]);
let queryString = `/filter_brief?`;
// queryString += paramsArray.join('&');
queryString += params.join("&");//直接用params,而不是paramsArray,因为paramsArray不是实时的
setQuery(queryString);
if (list.length == 0) {
getGroups(queryString, false);
} else {
setList([]);
getGroups(queryString, false);
}
}, [ volume_max, volume_min, liquidity_min, liquidity_max, end_date_min, end_date_max, is_closed, featured, search, category_ids, allTabsVisible, ]);
这样就能发送正确的请求了,btn,这还没完 🙉
使用redux store保留了我切换到主页之前点击的筛选项
当我不在filter这个页面,而是切换到主页,再切换到filter页面的时候,数据没有显示,本来是要展示没有拼贴任何筛选项的请求(即/filter_brief? )返回的数据的,结果一条数据都没有,查了网络请求,发现是这样的 /filter_brief?liquidity_min=10000&liquidity_max=50000&page=1 好家伙,使用redux store保留了我切换到主页之前点击的筛选项..
解决方法:
在每个模块的slice里面再定义一个reset方法将值设置为默认, 在filter页面的useEffect里去调用这些方法,这样首次挂载后就会清除store里面存储的数据了,store里面就都是默认值,请求就只是原来所有数据的了
在每个模块的slice里
// store.ts
import { createSlice } from '@reduxjs/toolkit';
// Define the state interface
interface endDateSliceState {
end_date_min: string | null | undefined;
end_date_max: string | null | undefined;
}
// Define the initial state
const initialState: endDateSliceState = {
end_date_min: null,
end_date_max: null,
};
// Create a slice with actions and reducer
export const endDateSlice = createSlice({
name: 'endDateSlice',
initialState,
reducers: {
setEndDateMin: (state: any, { payload }) => {
state.end_date_min = payload.end_date_min;
},
setEndDateMax: (state: any, { payload }) => {
state.end_date_max = payload.end_date_max;
},
//恢复默认值的方法
resetEndDateValue: (state: any) => {
state.end_date_min = initialState.end_date_min;
state.end_date_min = initialState.end_date_max;
}
},
});
// Export the actions and reducer
export const { setEndDateMin, setEndDateMax, resetEndDateValue } = endDateSlice.actions;
export default endDateSlice.reducer;
<Link href="/" style={{ textDecoration: "none", color: "#fff" }}>
<Box
className={styles.logoContainer}
onClick={resetDataToDefault}//点击logo恢复默认值
>
<Box
component="img"
width={{ sm: "40px", xs: "40px" }}
src="/styles/logo.png"
/>
<Typography fontWeight="700" marginLeft="5px" whiteSpace="nowrap">
logo
</Typography>
</Box>
</Link>
const resetDataToDefault = () => {
dispatch(resetValue());
dispatch(resetLiquidityValue());
dispatch(resetStatusValue());
dispatch(resetEndDateValue());
dispatch(resetSearchValue());
dispatch(resetCategoryIdValue());
dispatch(resetFeaturedValue());
};
在filter:
useEffect(() => {
dispatch(resetValue());
dispatch(resetLiquidityValue());
dispatch(resetStatusValue());
dispatch(resetEndDateValue());
dispatch(resetSearchValue());
dispatch(resetCategoryIdValue());
}, [ ]);
点击按钮加载更多
还有数据的加载,这里一开始是去请求第一页的数据,滑倒底部有个查看更多的按钮,点击就要去发送page+1的请求,直到拿到全部数据。这里也是要和其他的参数条件在一起: 首先在每次请求到数据后判断还有没有数据要拿 ,如果有就展示查看更多按钮
useEffect(() => {
if (total && list.length >= total) {
// 请求到的数据还不够 要让page+1之后继续请求
setHasMore(false);
}
}, [list]);
//...
{hasMore ? (
<Box display="flex" justifyContent="center">
<Button
sx={{
background: "#22262F",
color: "#eee",
marginTop: "0.5rem",
}}
onClick={handleSeeMoreClick}
>
See More
</Button>
</Box>
) : list.length !== 0 ? (
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
marginTop: "50px",
}}
>
<Typography color="rgba(255,255,255,.7)">
—— Rock Bottom ——
</Typography>
<img
src="image"
alt=""
width="80"
height="80"
/>
{/* <bottomImg/> */}
</Box>
) : null}
点击查看更多按钮调用的函数
const handleSeeMoreClick = () => {
// 拿到完整的请求参数数组paramsArray后,遍历,查看当前的page是第几页,然后加一,其他的参数原样返回
let updatedParams = paramsArray.map((param) => {
if (param?.startsWith("page=")) {
let currentPage = parseInt(param.split("=")[1]);
let updatedPage;
if (list && total) {
updatedPage = currentPage + 1;
setPage(updatedPage);
return "page=" + updatedPage;
}
}
// For other parameters, return them unchanged
return param;
});
setParamsArray(updatedParams);
let queryString = `/market/filter_brief?` + updatedParams.join("&");
getGroups(queryString, true);//点击查看更多就让isAddMore为true
};
最后还有一个点,在点击查看更多的时候,我们是要将请求到的数据添加到原有的数据上,而我们在做条件筛选的时候,是想要在已有的数据中筛出满足条件的数据:
const getGroups = async (queryString, isAddMore) => {
//...
isAddMore ? setList([...list, ...tempList]) : setList([...tempList]);
}
本来我是将isAddMore作为state的:
// const [isAddMore, setIsAddMore] = useState(false);
但是这样子在handleSeeMoreClick的时候调用getGroups就不是直接调用,用useEffect去监听isAddMore,变化就调用getGroups,而handleSeeMoreClick要传给getGroups函数queryString,虽然updatedParams存在setParamsArray中,但是这样有异步问题,emm就这个东西也卡了很久,各种set和useEffect太复杂,直接用参数传给getGroups这样来控制isAddMore的值反而更方便,一步到位