繁体   English   中英

React.js:如何在 Select 选项中设置默认值?

[英]React.js: How to set default value in Select option?

我正在尝试使用custom hooks在 React 中实现select-option ,并在尝试在select option中设置默认值时遇到问题。
UI中获取的数据中,来自 web API,我能够显示基于类别的selected data (在我的例子中是美食)。 但是当我 select 默认值显示All数据时,state 不会更新。
另一个问题是关于select option中的duplicated values 我需要具有唯一值作为option values 我正在考虑以这种方式获得独特的价值

 <option key={restaurant.id}>{[...new Set(restaurant.cuisine)]}</option>

但这会删除重复的字符,但不会duplicated values

代码如下。
Hooks/useRestaurants 组件

import React, { useState, useEffect } from "react";

const useRestaurants = (cuisine) => {
  const [allRestaurants, setAllRestaurants] = useState([]);

  useEffect(() => {
    fetch("https://redi-final-restaurants.herokuapp.com/restaurants")
      .then((res) => res.json())
      .then((result) => setAllRestaurants(result.results))
      .catch((e) => console.log("error"));
  }, []);

  useEffect(() => {
    if (cuisine === "All") {
      const filterRestaurants = [...allRestaurants].filter((restaurant) => // here is my try
       restaurant.cuisine.toLowerCase().includes(cuisine.toLowerCase())//code here doesn't work
      );
      setAllRestaurants(filterRestaurants);
    } else {
      const filterRestaurants = [...allRestaurants].filter((restaurant) =>
        restaurant.cuisine.toLowerCase().includes(cuisine.toLowerCase())
      );
      setAllRestaurants(filterRestaurants);
    }
  }, [cuisine]);

  return [allRestaurants];
};

export default useRestaurants;

App.js 组件

import React, { useState } from "react";

import useRestaurants from "./useRestaurants";
import Form from "./Form";
import Restaurant from "./Restaurant";
import "./styles.css";

export default function App() {
  const [cuisine, setCuisine] = useState("All");
  const [allRestaurants] = useRestaurants(cuisine);

  const onChangeHandler = (e) => {
    setCuisine(e.target.value);
  };

  return (
    <div className="App">
      <Form
        onChangeHandler={onChangeHandler}
        allRestaurants={allRestaurants}
        cuisine={cuisine}
        setCuisine={setCuisine}
      />
      {allRestaurants &&
        allRestaurants.map((restaurant) => (
          <Restaurant restaurant={restaurant} key={restaurant.id} />
        ))}
    </div>
  );
}

和 Form.js 组件

import React from "react";

const Form = ({ allRestaurants, cuisine, onChangeHandler }) => {
  return (
    <select onChange={onChangeHandler} value={cuisine}>
      <option value={cuisine}>All</option>
      {allRestaurants.map((restaurant) => (
        <option key={restaurant.id}>{restaurant.cuisine}</option>
      ))}
    </select>
  );
};

export default Form;

任何帮助将不胜感激。

执行过滤的 useRestaurants 中的useRestaurants缺少依赖数组中的allRestaurants 这意味着初始值(一个空数组)将始终在该 useEffect 中使用。 因此,更改菜式会将allRestaurants设置为空数组。 但是,您不能将allRestaurants添加到依赖项数组并在效果内进行设置。 这将导致它无限循环。 解决方案是不使用效果 - 只需创建过滤结果并将其作为单独的值或代替allRestaurants

// useRestaurants.js
import { useState, useMemo, useEffect } from "react";

const useRestaurants = (cuisine) => {
  const [allRestaurants, setAllRestaurants] = useState([]);

  useEffect(() => {
    fetch("https://redi-final-restaurants.herokuapp.com/restaurants")
      .then((res) => res.json())
      .then((result) => setAllRestaurants(result.results))
      .catch((e) => console.log("error"));
  }, []);

  const filteredRestaurants = useMemo(() => {
    return cuisine === "All"
      ? allRestaurants
      : allRestaurants.filter((restaurant) =>
          restaurant.cuisine.toLowerCase().includes(cuisine.toLowerCase())
        );
  }, [cuisine, allRestaurants]);

  return [allRestaurants, filteredRestaurants];
};

export default useRestaurants;

要修复重复的美食值,您需要创建 Set 然后过滤该结果。 您的表单仍在过滤所有allRestaurants并且{[...new Set(restaurant.cuisine)]}只是创建一个具有单个值的数组。

// Form.js
import React from "react";

const Form = ({ allRestaurants, cuisine, onChangeHandler }) => {
  const cuisines = Array.from(new Set(allRestaurants.map((r) => r.cuisine)));

  return (
    <select onChange={onChangeHandler} value={cuisine}>
      <option value='All'}>All</option>
      {cuisines.map((cuisine) => (
        <option id={cuisine}>{cuisine}</option>
      ))}
    </select>
  );
};

export default Form;

记得在 App.js 中遍历过滤后的餐厅

...
const [allRestaurants, filteredRestaurants] = useRestaurants(cuisine);

...
return (
  ...
  {filteredRestaurants &&
    filteredRestaurants.map((restaurant) => (
      <Restaurant restaurant={restaurant} key={restaurant.id} />
  ))}
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM