React hooks useState 数组
React hooks useState Array
我尝试在此处查找重置 useState
数组值,但找不到任何对数组值的引用。
正在尝试将下拉值从初始状态更改为 allowedState 值。我在这里使用钩子方法来设置使用 setStateValues
的值。如果我评论那行代码,它会显示下拉列表。我不明白为什么我不能使用 setStateValues
方法来重置状态变量值。
我收到以下错误:
Too many re-renders. React limits the number of renders to prevent an infinite loop
这里有什么问题吗?
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);
你不应该在渲染函数中设置状态(或做任何其他有副作用的事情)。使用钩子时,可以使用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
块。
尽量保持最小状态。不需要存储
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>);
)
}
接受的答案显示了 setState 的正确方法,但它不会导致功能良好的 select 框。
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);
扩展 Ryan 的回答:
每当调用 setStateValues 时,React re-renders 你的组件,这意味着 StateSelector
组件函数的函数体得到 re-executed。
反应 docs:
setState() will always lead to a re-render unless
shouldComponentUpdate() returns false.
本质上,您正在设置状态:
setStateValues(allowedState);
导致 re-render,然后导致函数执行,依此类推。因此,循环问题。
为了说明这一点,如果您将超时设置为:
setTimeout(
() => setStateValues(allowedState),
1000
)
'too many re-renders' 问题到此结束。
在您的例子中,您正在处理一个 side-effect,它在您的组件函数中由 UseEffect
处理。您可以阅读更多相关信息 here。
并不总是需要使用状态你可以简单地这样做
let paymentList = [
{"id":249,"txnid":"2","fname":"Rigoberto"}, {"id":249,"txnid":"33","fname":"manuel"},]
然后在像这样的地图循环中使用您的数据,在我的例子中它只是一个 table,我相信你们中的许多人都在寻找相同的数据。这是你如何使用它。
<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>
//get value
const valor1 = event.target.elements.valor1.value;
//add to value object
const todo = {
valor1,
}
//push to new value or your state
setValor(prevLista =>{
return prevLista.concat(todo)
})
}
我尝试在此处查找重置 useState
数组值,但找不到任何对数组值的引用。
正在尝试将下拉值从初始状态更改为 allowedState 值。我在这里使用钩子方法来设置使用 setStateValues
的值。如果我评论那行代码,它会显示下拉列表。我不明白为什么我不能使用 setStateValues
方法来重置状态变量值。
我收到以下错误:
Too many re-renders. React limits the number of renders to prevent an infinite loop
这里有什么问题吗?
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);
你不应该在渲染函数中设置状态(或做任何其他有副作用的事情)。使用钩子时,可以使用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
块。
尽量保持最小状态。不需要存储
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>);
)
}
接受的答案显示了 setState 的正确方法,但它不会导致功能良好的 select 框。
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);
扩展 Ryan 的回答:
每当调用 setStateValues 时,React re-renders 你的组件,这意味着 StateSelector
组件函数的函数体得到 re-executed。
反应 docs:
setState() will always lead to a re-render unless shouldComponentUpdate() returns false.
本质上,您正在设置状态:
setStateValues(allowedState);
导致 re-render,然后导致函数执行,依此类推。因此,循环问题。
为了说明这一点,如果您将超时设置为:
setTimeout(
() => setStateValues(allowedState),
1000
)
'too many re-renders' 问题到此结束。
在您的例子中,您正在处理一个 side-effect,它在您的组件函数中由 UseEffect
处理。您可以阅读更多相关信息 here。
并不总是需要使用状态你可以简单地这样做
let paymentList = [
{"id":249,"txnid":"2","fname":"Rigoberto"}, {"id":249,"txnid":"33","fname":"manuel"},]
然后在像这样的地图循环中使用您的数据,在我的例子中它只是一个 table,我相信你们中的许多人都在寻找相同的数据。这是你如何使用它。
<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>
//get value
const valor1 = event.target.elements.valor1.value;
//add to value object
const todo = {
valor1,
}
//push to new value or your state
setValor(prevLista =>{
return prevLista.concat(todo)
})
}