【问题标题】:React TypeScript right way to set select value and stateReact TypeScript 设置选择值和状态的正确方法
【发布时间】:2021-05-19 17:09:56
【问题描述】:

我正在尝试在我的 React 项目中学习使用 TypeScript。

我为传入的数据格式(名称和网址)做了一个类型。

type PokedexType = {
    name: string;
    url: string;
}

API 返回的数据是一个对象数组(带有名称和 url)。

{
"results": [
        {
            "name": "national",
            "url": "https://pokeapi.co/api/v2/pokedex/1/"
        },
        {
            "name": "kanto",
            "url": "https://pokeapi.co/api/v2/pokedex/2/"
        },
        // ...
    ];
}

在我的useEffect() 中,我将这些对象存储在setState() 的状态中。

useEffect(() => {
  api.get('/pokedex')
    .then((response) => {
      setPokedex(response.data.results);
    })
    .catch((error) => {
      console.log(error);
    });
});

由于 API 返回一个数组,我对设置 useState() 的正确方法感到困惑。

// this works
const [pokedex, setPokedex] = useState<Array<PokedexType>>([{ name: "", url: "" }]);
// these also work
const [pokedex, setPokedex] = useState<PokedexType>({ name: "", url: "" });
const [pokedex, setPokedex] = useState<Array<PokedexType>>();
const [pokedex, setPokedex] = useState(); // (with checking)

我知道指定类型是为了类型检查,但是如果状态立即被覆盖,这有关系吗?

我正在尝试将州名称 (i.name) 设置为我的选择的值,正确的方法是什么?既然 state 现在是一个数组,那么如何将值设置为相应的属性(像这样)?

<select value={pokedex.name}>

【问题讨论】:

  • 我不完全确定我理解你的问题。您是在问使用类型的意义何在?关于如何使用状态更改数组中项目的值,您还有第二个问题吗?
  • 不应该useState&lt;Array&lt;PokedexType&gt;&gt;([{ name: "", url: "" }]); 只是useState&lt;PokedexType[]&gt;([{ name: "", url: "" }]);
  • @azium 他们确实是两个独立的问题,我会尽量说清楚
  • @kimbaudi 两种方式都做同样的事情(arrname[]Array&lt;arrname&gt;
  • 默认 linter 规则是非复杂类型(即单个预定义类型)应该使用type[],复杂类型(定义内联/复合类型)应该使用Array&lt;{ name: string; url: string; }&gt; 或@987654336 @。我不知道这是否是一个仅偏好的 linter 规则,还是与类型解析速度有关。

标签: javascript arrays reactjs typescript select


【解决方案1】:

你不能只说pokedex.namepokedex 是一个数组,因此您必须遍历该数组。例如

//just a mock, will come from your ajax request
const pokedex = [
    {
        "name": "national",
        "url": "https://pokeapi.co/api/v2/pokedex/1/"
    },
    {
        "name": "kanto",
        "url": "https://pokeapi.co/api/v2/pokedex/2/"
    }
]

const Select = () => ( <select > 
      {pokedex.map(el => < option value = {el.name} >{el.name}</option>)}
</select>)


        // Render it
        ReactDOM.render( <
          Select / > ,
          document.getElementById("react")
        );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

再看看接口:

interface IPokedex {
    name: string;
    url: string;
}

const [pokedex, setPokedex] = useState<IPokedex[]>([{ name: "", url: "" }]);

【讨论】:

  • 好的,但是父标签select也有一个值属性,我应该绑定什么到这个值上?
  • 您的pokedex 结果没有预选值,因此您可以将select value 保留为空。这样,它将自行管理选择。如果您希望预先选择它或自己控制选择,那么您应该查看 React Controlled Components reactjs.org/docs/forms.html#controlled-components。但是你的最终目标是什么?
  • 哦,好吧,我认为需要为选择设置一个值才能显示正确的选项,我想如果我的&lt;option&gt; 有一个值,我可以将其省略。
  • 我调整了我的代码 sn-p,它不再有预选值。试试看。这回答了你的问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
  • 2020-12-04
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多