为什么我的组件没有使用 react-select 显示选项?

Why my component is not showing the options with react-select?

提问人:Caio Lagreca 提问时间:11/16/2023 更新时间:11/16/2023 访问量:22

问:

我正在尝试创建一个类别列表,用户将能够选择一个值。为此,我使用的是react-select,但是由于某种我无法弄清楚的原因,当用户单击按钮以显示选项时,我的选择选项不会呈现列表选项。我该怎么做才能使我的“选择”按钮正常工作并显示类别列表?

我的 CategoryDropdown 组件(使用 react-select):

import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import Select from "react-select";
import { fetchCategoriesAction } from "../../redux/slices/categories/categorySlice";

export const CategoryDropdown = (props) => {
  console.log(props);
  //dispatch action
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(fetchCategoriesAction());
  }, [dispatch]);

  //select categories
  const category = useSelector((state) => state?.category);
  const { categoryList, loading, appErr, serverErr } = category;

  let allCategories = [];

  if (categoryList) {
    allCategories = categoryList?.map((category) => ({
      label: category?.title,
      value: category?._id,
    }));
  }

  const handleChange = (value) => {
    props.onChange("category", value);
  };

  const handleBlur = () => {
    props.onBlur("category", true);
  };

  console.log("all cat", allCategories);
  return (
    <div style={{ margin: "1rem 0" }}>
      {loading ? (
        <h3 className="text-base text-green-600">
          Product categories list are loading, please wait...
        </h3>
      ) : (
        <Select
          onChange={handleChange}
          onBlur={handleBlur}
          id="category"
          options={allCategories}
          value={props?.value?.label}
        />
      )}
      {props?.error && (
        <div style={{ color: "red", marginTop: ".5rem" }}> {props?.error}</div>
      )}
    </div>
  );
};

我的 CreatePost 组件(按钮呈现的位置):

import { useFormik } from "formik";
import * as Yup from "yup";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { createPostAction } from "../../redux/slices/posts/postSlices";
import { CategoryDropdown } from "../Categories/CategoryDropdown";
import Dropzone from "react-dropzone";
import styled from "styled-components";

const formSchema = Yup.object({
  title: Yup.string().required("Title is required"),
  description: Yup.string().required("Description is required"),
  category: Yup.object().required("Category is required"),
  image: Yup.string().required("Image is required"),
});

//css for dropzone
const Container = styled.div`
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  border-width: 2px;
  border-radius: 2px;
  border-style: dashed;
  background-color: #fafafa;
  color: #bdbdbd;
  border-color: red;
  transition: border 0.24s ease-in-out;
  cursor: pointer;
`;

export default function CreatePost() {
  const dispatch = useDispatch();

  //select store data
  const post = useSelector((state) => state?.post);
  const { isCreated, loading, appErr, serverErr } = post;

  //formik
  const formik = useFormik({
    initialValues: {
      title: "",
      description: "",
      category: "",
      image: "",
    },
    onSubmit: (values) => {
      const data = {
        category: values?.category?.label,
        title: values?.title,
        description: values?.description,
        image: values?.image,
      };
      //dispatch the action
      dispatch(createPostAction(data));
    },
    validationSchema: formSchema,
  });

  const navigate = useNavigate();
  if (isCreated) {
    navigate("/posts");
  }
  return (
    <>
      <div className="min-h-screen bg-gray-900 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
        <div className="sm:mx-auto sm:w-full sm:max-w-md">
          <h2 className="mt-6 text-center text-3xl font-extrabold text-gray-300">
            Create Post
          </h2>
          <p className="mt-2 text-center text-sm text-gray-600">
            <p className="font-medium text-green-600 hover:text-indigo-500">
              Share your ideas to the word. Your post must be free from
              profanity
            </p>
          </p>
          {appErr || serverErr ? (
            <p className="mt-2 text-center text-lg text-red-600">
              {appErr || serverErr}
            </p>
          ) : null}
        </div>
        <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
          <div className="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
            <form onSubmit={formik.handleSubmit} className="space-y-6">
              <div>
                <label
                  htmlFor="email"
                  className="block text-sm font-medium text-gray-700"
                >
                  Title
                </label>
                <div className="mt-1">
                  {/* Title */}
                  <input
                    value={formik.values.title}
                    onChange={formik.handleChange("title")}
                    onBlur={formik.handleBlur("title")}
                    id="title"
                    name="title"
                    type="title"
                    autoComplete="title"
                    className="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
                  />
                </div>
                {/* Err msg */}
                <div className="text-red-500">
                  {formik?.touched?.title && formik?.errors?.title}
                </div>
              </div>
              <label
                htmlFor="category"
                className="block text-sm font-medium text-gray-700"
              >
                Select Category
              </label>
              <CategoryDropdown
                value={formik.values.category?.label}
                onChange={formik.setFieldValue}
                onBlur={formik.setFieldTouched}
                error={formik.errors.category}
                touched={formik.touched.category}
              />
              <div>
                <label
                  htmlFor="password"
                  className="block text-sm font-medium text-gray-700"
                >
                  Description
                </label>
                {/* Description */}
                <textarea
                  value={formik.values.description}
                  onChange={formik.handleChange("description")}
                  onBlur={formik.handleBlur("description")}
                  rows="5"
                  cols="10"
                  className="rounded-lg appearance-none block w-full py-3 px-3 text-base text-center leading-tight text-gray-600 bg-transparent focus:bg-transparent  border border-gray-200 focus:border-gray-500  focus:outline-none"
                  type="text"
                ></textarea>
                {/* Image Component */}
                <label
                  htmlFor="image"
                  className="block text-sm font-medium text-gray-700 mt-3 mb-1"
                >
                  Select Image
                </label>
                <Container className="container bg-gray-600">
                  <Dropzone
                    onDrop={(acceptedFiles) => {
                      formik.setFieldValue("image", acceptedFiles[0]);
                    }}
                    accept="image/jpeg, image/png"
                    onBlur={formik.handleBlur("image")}
                  >
                    {({ getRootProps, getInputProps }) => {
                      return (
                        <div className="container">
                          <div
                            {...getRootProps({
                              className: "dropzone",
                              onDrop: (event) => event.stopPropagation(),
                            })}
                          >
                            <input {...getInputProps()} />
                            <p className="text-gray-300 text-lg cursor-pointer">
                              Click here to select Image
                            </p>
                          </div>
                        </div>
                      );
                    }}
                  </Dropzone>
                </Container>
                {/* Err msg */}
                <div className="text-red-500">
                  {formik.touched.description && formik?.errors?.description}
                </div>
              </div>
              <div>
                {/* Submit btn */}
                {loading ? (
                  <button
                    type="submit"
                    className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-600 cursor-none"
                  >
                    Loading...
                  </button>
                ) : (
                  <button
                    type="submit"
                    className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                  >
                    Create
                  </button>
                )}
              </div>
            </form>
          </div>
        </div>
      </div>
    </>
  );
}

同样在这里,我的浏览器打印了一张带有控制台 .log 的打印件,显示了类别列表:

enter image description here

reactjs 渲染 react-select

评论


答: 暂无答案