我制作了一个数组来存储来自API的项的数据,并try 在我的页面中显示它.

但是这些项目没有加载到页面上.

包含这些项的数组如下所示

const allCategory = ["All",...new Set(filteredData.map((curElem)=> {return curElem.Category}))];

通过这种方式,我将显示数组中的项:


 const [catItems, setCatItems] = useState(allCategory);


    const filterItem = (category) =>{

        if(category === "All"){
            setData(mainArray);
            return;
        }

        const updatedItems = mainArray.filter((curElem)=>{
            return curElem.Category === category;
        })
        setData(updatedItems);
    }
<div>
{
 catItems.map((curClem, index)=>{
    return <li key={index} onClick={() => filterItem(curClem)}>{curClem}</li>
                        })
                    }
</div>

当我try 加载Use Effect中的数组时,整个页面变为空白:

useEffect(() => {
        async function fetchData(){
          try {
            const response = await fetch('https://63b6952d1907f863aafa9342.mockapi.io/menu/')
            const data = await response.json();
            setData(data);
            setMainArray(data);
            setCatItems(data);
          } catch (error) {
            console.error(error);
          }
        }
    
        fetchData();
      }, []);

我想我在加载Use Effect中的数组时犯了一个错误.

告诉我我面临的问题是什么,或者我在代码中犯了什么错误,并帮助我解决它.

我的数组中的数据没有显示在页面上,我try 在Use Effect中调用它们,但不起作用.我想我在Use Effect中调用设置状态是一个错误.

我在代码中提供了沙箱链接以获取更多详细信息:

https://codesandbox.io/s/qr-menu-smvr6h?file=/src/App.js

推荐答案

allCategories是被认为是派生状态.它是从当前的data状态和vegOnly状态派生出来的.data状态是在初始渲染时获取的,并在初始渲染时更新105,因此它不能用于计算初始catItems状态.

派生状态不属于REACTIVE状态,因为它很容易从其他现有状态/props /等派生.这意味着UI应该直接引用计算的allCategoryarray.

...

const [data, setData] = useState([]);
const [vegOnly, setVegOnly] = useState(false);

useEffect(() => {
  async function fetchData() {
    try {
      const response = await fetch(
        "https://63b6952d1907f863aafa9342.mockapi.io/menu/"
      );
      const data = await response.json();
      setData(data);
      setMainArray(data);
    } catch (error) {
      console.error(error);
    }
  }

  fetchData();
}, []);

...

const filteredData =
  vegOnly === false ? data : data.filter((item) => item.Type === "veg"); 
  //from above to here for filter veg only

const allCategory = [
  "All",
  ...new Set(filteredData.map((curElem) => curElem.Category))
]; // 3rd step to make it array

...

<ul>
  {allCategory.map((curClem, index) => {
    return (
      <li key={index} onClick={() => filterItem(curClem)}>
        {curClem}
      </li>
    );
  })}
</ul>

有相当多的冗余/不必要的状态.所有的"过滤数据"也被认为是派生状态.您应该存储数据数组的一次副本状态,以及过滤条件,而不是数组的重复项.

示例:

const App = () => {
  const [data, setData] = useState([]); //solved from stackoverflow
  const [search, setSearch] = useState("");
  const [category, setCategory] = useState("All");
  const [vegOnly, setVegOnly] = useState(false);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch(
          "https://63b6952d1907f863aafa9342.mockapi.io/menu/"
        );
        const data = await response.json();
        setData(data);
      } catch (error) {
        console.error(error);
      }
    }

    fetchData();
  }, []);

  const handleVegInputChange = (e) => {
    const { checked } = e.target;
    setVegOnly(checked);
  };

  // filter the data inline by the different filtering conditons
  // and selected category.
  const filteredData = data
    .filter((item) => {
      return item.Name.toLowerCase().includes(search.toLowerCase());
    })
    .filter((item) => {
      if (vegOnly) {
        return item.Type === "veg";
      }
      return true;
    })
    .filter((item) => {
      if (category !== "All") {
        return item.Category === category;
      }
      return true;
    });

  // Derive the categories from the data array
  const allCategory = [
    "All",
    ...new Set(data.map((curElem) => curElem.Category))
  ]; // 3rd step to make it array

  // Set the selected filtering category
  const filterItem = (category) => {
    setCategory(category);
  };

  return (
    <div className="first">
      ...
      ...
      <div className="resinfo2">
        <div className="rescategory">
          <ul>
            {allCategory.map((curClem, index) => {
              return (
                <li
                  key={index}
                  // Style the selected category
                  style={{
                    color: curClem === category ? "lightgreen" : "inherit"
                  }}
                  onClick={() => filterItem(curClem)}
                >
                  {curClem}
                </li>
              );
            })}
          </ul>
        </div>

        <div className="resitems">
          <div className="box">
            <input
              type="text"
              className="search-input"
              placeholder="Search for dishes"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
            <img src="/images/search.png" />
          </div>

          <div className="contents">
            {data ? (
              <div>
                <div className="checkbox">
                  <label>
                    <input
                      type="checkbox"
                      value={vegOnly}
                      onChange={handleVegInputChange}
                    />
                    Veg Only
                  </label>
                </div>
                <div className="items">
                  {filteredData.map((item) => (
                    <div className="itemslist" key={item.id}>
                      <ul>
                        <li
                          className={
                            item.Type === "veg" ? "veg" : "non-veg"
                          }
                        ></li>
                        <li>{item.Name}</li>
                        <li>₹ {item.Price}</li>
                        <img src="/images/pizza1.jpg" />
                        <div className="hr"></div>
                      </ul>
                    </div>
                  ))}
                </div>
              </div>
            ) : (
              <div className="loading">Loading...</div>
            )}
          </div>
        </div>
        <div className="rescart"></div>
      </div>
    </div>
  );
};

Edit data-is-not-displayed-from-the-array-on-page-load

Reactjs相关问答推荐

无法在jest中发布行动

生成Reaction Vite应用程序的停靠容器时无法识别环境变量

这两个子元素在Reaction Native中使用的有什么不同?

如何解决Reaction中遗留的上下文API错误?

使用VITE的Reaction应用程序的配置是否正确?

在一个事件处理程序中进行多次调度是个好主意吗?

useMemo 依赖项的行为

这个简单的React组件为什么会多次渲染?

为什么我会收到此错误:无法在我的react 包上读取 null 的属性(读取useState)?

为什么刷新页面时我的localStorage PET值变成空字符串?

在 React 中使用复选框管理状态

React Final Form - 单选按钮在 FieldArray 中不起作用

当我在 useEffect 中使用 useDispatch 时,我的组件继续渲染

vdom 最终更新了 dom(在比较之后)任何 dom 更改实际上应该触发整个树的重绘和回流,那么 vdom 有什么用?

React Router 6.4CreateBrowserRouter子元素不显示

调用 Jest 和服务方法的问题

为什么我从另一个组件收到错误?

警告:您在没有 `onChange` 处理程序的情况下为表单字段提供了 `value` 属性

如何从另一个切片中的不同切片获取状态并对其进行处理?

react 路由:router.ts:11 没有匹配的路由位置/管理