根据 React/Redux 中的提交重新呈现页面并调用 API
Rerendering page based on submission in React/Redux with Calling API
我正在尝试使用 Redux 调用 API,它会根据表单提交再次调用。
这意味着如果查询是 none,它会 returns 列出所有匹配查询的列表或 returns 列表。
// List.tsx
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { getFeatures, increasePage } from "../../redux/featuresSlice";
import { FeatureItem } from "../../components/featureItem";
interface IFeatureProp {
featureObject: any;
getFeaturesWith: any;
}
const FeatureList = ({
featureObject,
getFeaturesWith,
}: // page,
IFeatureProp) => {
const [keywords, setKeywords] = useState("");
const fetchData = async () => {
getFeaturesWith(featureObject.page, keywords);
};
const handleSubmit = (e: any) => {
e.preventDefault();
fetchData();
};
useEffect(() => {
console.log(keywords);
fetchData();
}, []);
return (
<div className="max-w-screen-xl mx-auto mt-8">
<div className="px-12">
<div className="relative">
<div className="relative">
<form onSubmit={handleSubmit}>
<div className="absolute top-0 bottom-0 left-0 flex items-center px-5">
</div>
<input
type="text"
placeholder="Search..."
value={keywords}
onChange={e => setKeywords(e.target.value)}
/>
</form>
</div>
<ul>
{featureObject.features
.map((c: any) => {
return (
<FeatureItem
id={c.id}
name={c.name}
desc={c.desc}
/>
);
})}
</ul>
</div>
</div>
</div>
);
};
function mapStateToProps(state: any) {
return { featureObject: state.featuresReducer.explore };
}
function mapDispatchToProps(dispatch: any) {
return {
getFeaturesWith: (page: any, keyword: string) =>
dispatch(getFeatures(page, keyword)),
increasePageWith: () => dispatch(increasePage(1)),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(FeatureList);
//featuresSlice.js
import { createSlice } from "@reduxjs/toolkit";
import api from "../api";
const featuresSlice = createSlice({
name: "features",
initialState: {
explore: {
page: 1,
features: [],
},
favs: [],
},
reducers: {
setExploreFeatures(state, action) {
const { explore } = state;
const { payload } = action;
payload.features.forEach(payloadFeature => {
const exists = explore.features.find(
savedFeature => savedFeature.id === payloadFeature.id
);
if (!exists) {
explore.features.push(payloadFeature);
}
});
state.explore.page = payload.page;
},
},
});
export const { setExploreFeatures, increasePage, setFavs, setFav } =
featuresSlice.actions;
export const getFeatures = (page, keyword) => async (dispatch, getState) => {
const {
usersReducer: { token },
} = getState();
try {
const {
data: { results },
} = await api.features(token, page, keyword);
dispatch(
setExploreFeatures({
features: results,
page: 1,
})
);
} catch (e) {
console.warn(e);
}
};
export default featuresSlice.reducer;
当我提交关键字时,它在后端按我预期的方式工作。
[07/Feb/2022 01:55:23] "GET /api/v1/features/?search=abcd HTTP/1.1" 200 3615
而且我只看到与 redux-debugger 中的查询匹配的列表。
但它不会重新呈现页面,这意味着我只能看到整个列表。
我可以做什么来更新状态?
问题是你的 reducer 正在改变 状态,这在 Redux 意识形态中永远不应该是这种情况。
相反,您应该创建一个新的状态对象(应用您的更改)并 return 它来自 reducer。如果您不想修改状态 - 只需 return 保持原始状态不变即可。你所有的减速器都应该是这样的。
reducers: {
setExploreFeatures(state, action) {
const { payload } = action;
const newFeatures = payload.features.filter(x => !state.explore.features.some(y => y.id === x.id));
return { ...state, explore: { ...state.explore, features: [...state.explore.features, ...newFeatures], page: payload.page } };
},
},
沿着这些路线^^
我正在尝试使用 Redux 调用 API,它会根据表单提交再次调用。 这意味着如果查询是 none,它会 returns 列出所有匹配查询的列表或 returns 列表。
// List.tsx
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { getFeatures, increasePage } from "../../redux/featuresSlice";
import { FeatureItem } from "../../components/featureItem";
interface IFeatureProp {
featureObject: any;
getFeaturesWith: any;
}
const FeatureList = ({
featureObject,
getFeaturesWith,
}: // page,
IFeatureProp) => {
const [keywords, setKeywords] = useState("");
const fetchData = async () => {
getFeaturesWith(featureObject.page, keywords);
};
const handleSubmit = (e: any) => {
e.preventDefault();
fetchData();
};
useEffect(() => {
console.log(keywords);
fetchData();
}, []);
return (
<div className="max-w-screen-xl mx-auto mt-8">
<div className="px-12">
<div className="relative">
<div className="relative">
<form onSubmit={handleSubmit}>
<div className="absolute top-0 bottom-0 left-0 flex items-center px-5">
</div>
<input
type="text"
placeholder="Search..."
value={keywords}
onChange={e => setKeywords(e.target.value)}
/>
</form>
</div>
<ul>
{featureObject.features
.map((c: any) => {
return (
<FeatureItem
id={c.id}
name={c.name}
desc={c.desc}
/>
);
})}
</ul>
</div>
</div>
</div>
);
};
function mapStateToProps(state: any) {
return { featureObject: state.featuresReducer.explore };
}
function mapDispatchToProps(dispatch: any) {
return {
getFeaturesWith: (page: any, keyword: string) =>
dispatch(getFeatures(page, keyword)),
increasePageWith: () => dispatch(increasePage(1)),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(FeatureList);
//featuresSlice.js
import { createSlice } from "@reduxjs/toolkit";
import api from "../api";
const featuresSlice = createSlice({
name: "features",
initialState: {
explore: {
page: 1,
features: [],
},
favs: [],
},
reducers: {
setExploreFeatures(state, action) {
const { explore } = state;
const { payload } = action;
payload.features.forEach(payloadFeature => {
const exists = explore.features.find(
savedFeature => savedFeature.id === payloadFeature.id
);
if (!exists) {
explore.features.push(payloadFeature);
}
});
state.explore.page = payload.page;
},
},
});
export const { setExploreFeatures, increasePage, setFavs, setFav } =
featuresSlice.actions;
export const getFeatures = (page, keyword) => async (dispatch, getState) => {
const {
usersReducer: { token },
} = getState();
try {
const {
data: { results },
} = await api.features(token, page, keyword);
dispatch(
setExploreFeatures({
features: results,
page: 1,
})
);
} catch (e) {
console.warn(e);
}
};
export default featuresSlice.reducer;
当我提交关键字时,它在后端按我预期的方式工作。
[07/Feb/2022 01:55:23] "GET /api/v1/features/?search=abcd HTTP/1.1" 200 3615
而且我只看到与 redux-debugger 中的查询匹配的列表。 但它不会重新呈现页面,这意味着我只能看到整个列表。
我可以做什么来更新状态?
问题是你的 reducer 正在改变 状态,这在 Redux 意识形态中永远不应该是这种情况。
相反,您应该创建一个新的状态对象(应用您的更改)并 return 它来自 reducer。如果您不想修改状态 - 只需 return 保持原始状态不变即可。你所有的减速器都应该是这样的。
reducers: {
setExploreFeatures(state, action) {
const { payload } = action;
const newFeatures = payload.features.filter(x => !state.explore.features.some(y => y.id === x.id));
return { ...state, explore: { ...state.explore, features: [...state.explore.features, ...newFeatures], page: payload.page } };
},
},
沿着这些路线^^