【问题标题】:React useSelector first time returns undefined, then everything works fineReact useSelector 第一次返回未定义,然后一切正常
【发布时间】:2020-10-13 18:27:30
【问题描述】:

所以我正在使用 MERN 堆栈制作一个迷你电子商务应用程序,我正在使用他的 id 为每个卖家获取产品,所以他是唯一可以编辑或删除自己产品的人,

在我的组件中,我从用户的 redux 状态中获取用户的 id,然后我使用该 id 为每个登录的卖家获取产品。(在 useEffect 中) 所以获取产品取决于用户,用户总是加载,登录后不需要获取。

问题是,只有在我第一次登录并渲染它给我的组件之后 TypeError:products.map 不是函数。但如果我刷新页面它工作正常 所以它不会第一次看到产品 idk 为什么即使用户在那里和 id 来启动获取功能。

function EditProducts() {
  const { user } = useSelector(state => state.userrr);
  const { loading, products } = useSelector(state => state.userProductsss);

  const dispatch = useDispatch();

  useEffect(() => {
    console.log(user);
    console.log(products);

    if (!user) {
      return;
    } else {
      let id = user._id;
      dispatch(fetchUserProducts(id));
    }
  }, [dispatch, user]);

  const deleteIt = id => {
    dispatch(deleteProduct(id))
      .then(res => {
        toast.success(res, { position: toast.POSITION.BOTTOM_LEFT });
      })
      .catch(error => {
        toast.error(error, {
          position: toast.POSITION.BOTTOM_LEFT,
          autoClose: false
        });
      });
  };
  console.log(products);
  return (
    <Container>
      <Table striped bordered hover variant='dark'>
        <thead>
          <tr>
            <th>category</th>
            <th>Description</th>
            <th>Price</th>
            <th>Edit</th>
          </tr>
        </thead>
        <tbody>
          {loading && (
            <tr>
              <td colSpan='4'>
                <Spinner animation='border' /> loading...{" "}
              </td>
            </tr>
          )}

          {!user && !loading && (
            <tr>
              <td colSpan='4'>Please Log in to access this page</td>
            </tr>
          )}
          {products.map(product => (
            <tr key={product._id}>
              <td>{product.name}</td>
              <td>{product.description}</td>
              <td>${product.price}</td>
              <td>
                <span className='btn btn-primary mr-3'>
                  <UpdateProductForm
                    id={product._id}
                    name={product.name}
                    description={product.description}
                    category={product.category}
                    price={product.price}
                    numberInStock={product.numberInStock}
                    productImage={product.productImage}
                  />
                </span>
                <Button className='btn btn-danger' onClick={() => deleteIt(product._id)}>
                  <FontAwesomeIcon icon={faTrash} />
                </Button>
              </td>
            </tr>
          ))}
        </tbody>
      </Table>
    </Container>
  );
}

export default EditProducts;

这是我的减速器

const productReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_USER_PRODUCTS_STARTED:
      return {
        ...state,
        loading: true
      };
    case FETCH_USER_PRODUCTS_SUCCESS:
      return {
        ...state,
        loading: false,
        error: null,
        products: action.payload.products
      };
    case FETCH_USER_PRODUCTS_FAILURE:
      return {
        ...state,
        loading: false,
        error: action.payload.error,
        success: null
      };
  default:
    return state;
}
};

这是动作

export const fetchUserProducts = userId => {
  return dispatch => {
    dispatch(fetchUserProductsStarted());

    axios
      .get(`/api/product/${userId}/products`)
      .then(res => {
        dispatch(fetchUserProductsSuccess(res.data));
      })
      .catch(error => {
        dispatch(fetchUserProductsFailure(error.message));
      });
  };
};

const fetchUserProductsStarted = () => {
  return {
    type: FETCH_USER_PRODUCTS_STARTED
  };
};

const fetchUserProductsSuccess = products => {
  return {
    type: FETCH_USER_PRODUCTS_SUCCESS,
    payload: {
      products
    }
  };
};

const fetchUserProductsFailure = error => {
  return {
    type: FETCH_USER_PRODUCTS_FAILURE,
    payload: {
      error
    }
  };
};

【问题讨论】:

  • 添加组件的JSX。
  • @Ramesh 完成.....

标签: node.js reactjs express redux react-redux


【解决方案1】:

所以问题是 useEffect 无法确保在此处第一次渲染之前加载用户数据:

const { user } = useSelector(state => state.userrr);

所以用户为空,因此无法根据用户ID获取产品。

我所做的是我在组件 useEffect 中再次加载了用户,以便它获取用户数据。

useEffect(() => {
    dispatch(loadUser());

    const id = user ? user._id : null;
    dispatch(fetchUserProducts(id));
  }, [ dispatch, id]);

【讨论】:

    猜你喜欢
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 2018-01-26
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多