根据 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 } };
    },
  },

沿着这些路线^^