反应Hooks useState Array

时间:2018-12-17 22:49:49

标签: reactjs react-hooks

我尝试在此处寻找重置useState数组值,但找不到对数组值的任何引用。

尝试将下拉值从初始状态更改为允许状态值。我在这里使用hooks方法来使用-setStateValues设置值。如果我注释该行代码,它将显示下拉列表。我不明白为什么不能使用setStateValues方法重置状态变量值。

我收到以下错误消息:“重新渲染太多。React限制了渲染数量,以防止无限循环。”

如果您在此处发现问题,请提供帮助。我会继续寻找。

/wiki/Hamilton_Mour%C3%A3o
/wiki/Michel_Temer
/wiki/C%C3%A2mara_dos_Deputados_do_Brasil
...

Should be:
    /wiki/Hamilton_Mourão
    /wiki/Michel_Temer
    /wiki/Câmara_dos_Deputados_do_Brasil
    ...

5 个答案:

答案 0 :(得分:7)

您不应在渲染功能内设置状态(或做其他有副作用的操作)。使用挂钩时,您可以为此使用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);

here it is in a code sandbox

我假设您最终要从某个动态源加载状态列表(否则,您可以直接使用allowedState,而根本不使用useState)。如果是这样,则用于加载列表的api调用也可以进入useEffect块内。

答案 1 :(得分:1)

尝试保持状态最小化。无需存储

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

状态。将永久物与变化分开

const ALL_STATE_VALS = [
    { id: 0,value: " --- Select a State ---" }
    { id: 1, value: "Alabama" },
    { id: 2, value: "Georgia" },
    { id: 3, value: "Tennessee" }
];

然后,您可以仅将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>);
   )
}

答案 2 :(得分:0)

可接受的答案显示了setState的正确方法,但不会导致选择框运行正常。

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

const initialValue = { id: 0,value: " --- Select a State ---" };

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

const StateSelector = () => {   
   const [ selected, setSelected ] = useState(initialValue);  

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

const rootElement = document.getElementById("root");
ReactDOM.render(<StateSelector />, rootElement);

答案 3 :(得分:0)

扩展赖安的答案:

无论何时调用setStateValues,React都会重新渲染您的组件,这意味着StateSelector组件函数的函数主体将被重新执行。

反应docs

  

setState()将始终导致重新渲染,除非   shouldComponentUpdate()返回false。

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

setStateValues(allowedState);

,它导致重新渲染,然后使函数执行,依此类推。这会导致循环问题。

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

     setTimeout(
    () => setStateValues(allowedState),
    1000
  )

它将结束“太多的重新渲染”问题。

UseEffect用于处理组件函数中的副作用。您可以详细了解here

答案 4 :(得分:0)

并非总是需要使用状态,您可以简单地做到这一点

let paymentList = [
    {"id":249,"txnid":"2","fname":"Rigoberto"}, {"id":249,"txnid":"33","fname":"manuel"},]

然后在这样的map循环中使用您的数据,在我的情况下,它只是一个表,我确定很多人都在寻找相同的数据。这是您的用法。

<div className="card-body">
            <div className="table-responsive">
                <table className="table table-striped">
                    <thead>
                        <tr>
                            <th>Transaction ID</th>
                            <th>Name</th>
                        </tr>
                    </thead>
                    <tbody>
                        {
                            paymentList.map((payment, key) => (
                                <tr key={key}>
                                    <td>{payment.txnid}</td>
                                    <td>{payment.fname}</td>
                                </tr>
                            ))
                        }
                    </tbody>
                </table>
            </div>
        </div>