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

时间:2021-04-27 08:39:05

标签: javascript reactjs typescript redux redux-saga

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

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,代码如下所示: 佐贺:

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);

1 个答案:

答案 0 :(得分:0)

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

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