首页 > 解决方案 > 即使我匹配状态,返回新状态并连接组件,我的组件功能在状态更改后也不会重新渲染,

问题描述

我在类似的帖子中研究过这个问题,但我就是想不通,我有点需要建议。所以基本上我的功能组件在我从减速器返回一个新状态后没有重新运行。减速器看起来像这样:

export interface ProductsTableState {
  products: Product[];
  isLoading: boolean;
}

const initialState: ProductsTableState = {
  products: [],
  isLoading: false,
};

export const ProductsTableReducer = (
  state = initialState,
  action: ProductsTableActionsInterface
): ProductsTableState => {
  switch (action.type) {
    case ProductsTableActionsEnum.GET_ALL_PRODUCTS_REQUEST:
      // CONSOLE LOG
      console.log("Request in REDUCER");
      return {
        ...state,
        isLoading: true,
      };
    case ProductsTableActionsEnum.GET_ALL_PRODUCTS_SUCCESS:
      console.log("Success in reducer");
      return {
        ...state,
        products: action.payload,
        isLoading: false,
      };
    default:
      return state;
  }
};

在第二种情况下,我在控制台中收到消息,因此正在运行。因此,在减速器中,我认为我返回了一个 NEW 状态,因此连接应该可以看到更改。因为阅读我看到了多个问题,如果您修改当前状态,它将不会被检测到,因此您需要返回一个新状态。

对于 saga 和 store,代码如下所示: Saga:

function* getAllProductsAsync() {
  try {
    const result: Product[] = yield call(() => getProducts());
    // CONSOLE LOG
    console.log("SAGA");
    console.log(result);

    yield put(getAllProductsSuccess(result));
  } catch (err) {
    yield put(getAllProductsError());
  }
}

export function* watchGetAllProductsAsync() {
  yield takeEvery(
    ProductsTableActionsEnum.GET_ALL_PRODUCTS_REQUEST,
    getAllProductsAsync
  );
}

并存储:

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const sagaMiddleware = createSagaMiddleware();

export const store = createStore(
  ProductsTableReducer,
  composeEnhancers(applyMiddleware(sagaMiddleware))
);

sagaMiddleware.run(watchGetAllProductsAsync);

export interface AppState {
  products: ProductsTableState;
}

我认为最重要的是我遇到问题的功能组件。主要是一个 Redux - Axios React 应用程序。所以实际发生的是,当我第一次加载页面时,我什么也没有。如果我在这里评论一行并用我的产品保存页面重新加载,因为在第二次渲染时,产品在状态下是可见的。据我所知,我认为我的问题应该与 mapStateWithProps 和连接有关,但对我来说看起来不错。

interface ProductsTableProps {
  products: Product[];
  isLoading: boolean;
}

export const TableProducts = (props: ProductsTableProps) => {
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getAllProductsRequest());
  }, []);

  // CONSOLE LOG
  console.log(store.getState().products);

  // CONSOLE LOG
  console.log(props.products);

  const classes = useStyles();
  const items = store.getState().products.map((product) => (
    <tr className={classes.trStyle}>
      <td className={classes.thtdStyle}>{product.productCategoryDto.name}</td>
      <td className={classes.thtdStyle}>{product.name}</td>
      <td className={classes.thtdStyle}>{product.price}</td>
      <td key={product.id}>
        <Link to={{ pathname: `/product/${product.id}`, state: { product } }}>
          <IconButton className={classes.buttonStyle}>
            <InfoIcon />
          </IconButton>
        </Link>
      </td>
    </tr>
  ));

  return (
    <table className={classes.tableStyle}>
      <thead className={classes.theadStyle}>
        <tr>
          <th className={classes.thtdStyle}>Category</th>
          <th className={classes.thtdStyle}>Name</th>
          <th className={classes.thtdStyle}>Price</th>
          <th className={classes.thtdStyle}>Description</th>
        </tr>
      </thead>
      <tbody className={classes.trStyle}>{items}</tbody>
    </table>
  );
};

const mapStateToProps = (state: AppState) => ({
  products: state.products.products,
  isLoading: state.products.isLoading,
});

const mapDispatchToProps = (dispatch: Dispatch) => ({
  getAllProd: () => dispatch(getAllProductsRequest()),
  getAllProdSuccess: (products: Product[]) =>
    dispatch(getAllProductsSuccess(products)),
});

export default connect(mapStateToProps, {
  getAllProductsRequest,
  getAllProductsSuccess,
})(TableProducts);

标签: javascriptreactjstypescriptreduxredux-saga

解决方案


我在 中看到了问题mapStateToProps。您可以尝试像这样更新:

const mapStateToProps = (state: AppState) => ({
  products: state.products,
  isLoading: state.isLoading,
});

推荐阅读