react Hooks useState Array

sha*_*avi 12 reactjs react-hooks

我试图在这里寻找重置useState数组值,但找不到对数组值的任何引用.

尝试将下拉值从初始状态更改为allowedState值.我在这里使用hooks方法使用--setStateValues设置值.如果我评论该行代码,它会显示下拉列表.我无法理解为什么我不能使用setStateValues方法来重置状态变量值.

我收到以下错误:"太多重新渲染.React限制渲染的数量,以防止无限循环".

如果你在这里看到错误,请帮忙.我会继续寻找.

    import React, { useState } from "react"; 
    import ReactDOM from "react-dom";

    const StateSelector = () => {   
    const initialValue = [
    { id: 0,value: " --- Select a State ---" }];

      const allowedState = [
        { id: 1, value: "Alabama" },
        { id: 2, value: "Georgia" },
        { id: 3, value: "Tennessee" }
        ];

      const [stateOptions, setStateValues] = useState(initialValue);  
      // initialValue.push(...allowedState);

      console.log(initialValue.length);

      setStateValues(allowedState); // Not sure why cannot I reset the state in here for an array.

         return (<div>
          <label>Select a State:</label>
          <select>
            {stateOptions.map((localState, index) => (
              <option key={localState.id}>{localState.value}</option>
            ))}
          </select>
        </div>   ); };

    const rootElement = document.getElementById("root");
    ReactDOM.render(<StateSelector />, rootElement);
Run Code Online (Sandbox Code Playgroud)

Rya*_*ell 12

你不应该在渲染函数中设置状态(或者做任何有副作用的事情).使用钩子时,您可以使用useEffect它.

以下版本有效:

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

const StateSelector = () => {
  const initialValue = [
    { id: 0, value: " --- Select a State ---" }];

  const allowedState = [
    { id: 1, value: "Alabama" },
    { id: 2, value: "Georgia" },
    { id: 3, value: "Tennessee" }
  ];

  const [stateOptions, setStateValues] = useState(initialValue);
  // initialValue.push(...allowedState);

  console.log(initialValue.length);
  // ****** BEGINNING OF CHANGE ******
  useEffect(() => {
    // Should not ever set state during rendering, so do this in useEffect instead.
    setStateValues(allowedState);
  }, []);
  // ****** END OF CHANGE ******

  return (<div>
    <label>Select a State:</label>
    <select>
      {stateOptions.map((localState, index) => (
        <option key={localState.id}>{localState.value}</option>
      ))}
    </select>
  </div>);
};

const rootElement = document.getElementById("root");
ReactDOM.render(<StateSelector />, rootElement);
Run Code Online (Sandbox Code Playgroud)

这里是一个代码沙箱.

我假设你想最终从一些动态源加载状态列表(否则你可以直接使用allowedState而不使用useState).如果是这样,那个加载列表的api调用也可以进入useEffect块内.


Ben*_*arp 7

尽量保持你的状态最小。无需存储

   const initialValue = [
    { id: 0,value: " --- Select a State ---" }];
Run Code Online (Sandbox Code Playgroud)

作为状态。将永久与变化分开

const ALL_STATE_VALS = [
    { id: 0,value: " --- Select a State ---" }
    { id: 1, value: "Alabama" },
    { id: 2, value: "Georgia" },
    { id: 3, value: "Tennessee" }
];
Run Code Online (Sandbox Code Playgroud)

然后你可以只存储 id 作为你的状态:

const StateSelector = () =>{
  const [selectedStateOption, setselectedStateOption] = useState(0);

  return (
    <div>
      <label>Select a State:</label>
      <select>
        {ALL_STATE_VALS.map((option, index) => (
          <option key={option.id} selected={index===selectedStateOption}>{option.value}</option>
        ))}
      </select>
    </div>);
   )
}
Run Code Online (Sandbox Code Playgroud)


Joe*_*l H 5

扩展瑞安的答案:

每当调用 setStateValues 时,React 都会重新渲染您的组件,这意味着组件函数的函数StateSelector体会重新执行。

反应文档

setState() 总是会导致重新渲染,除非 shouldComponentUpdate() 返回 false。

本质上,您通过以下方式设置状态:

setStateValues(allowedState);
Run Code Online (Sandbox Code Playgroud)

导致重新渲染,然后导致函数执行,等等。因此,循环问题。

为了说明这一点,如果您将超时设置如下:

  setTimeout(
    () => setStateValues(allowedState),
    1000
  )
Run Code Online (Sandbox Code Playgroud)

这结束了“太多重新渲染”问题。

就您而言,您正在处理副作用,这是UseEffect在组件函数中处理的。你可以在这里读更多关于它的内容。