[英]setState() doesn't update value
我正在嘗試更新組件的狀態,但無法正常工作。 我有主頁容器組件=>嵌套的Navbar容器組件=>嵌套的NavItem UI組件。 同樣在主頁上,我有AddNavItem容器組件,應將項目添加到Navbar。 看起來像這樣:
Main
|
|--NavBar
| |
| |--NavItem
|
|--AddNavItem
這是我的主頁代碼:
import React, { Component } from 'react';
import Navbar from '../nav/Navbar'
import AddNavItem from '../fields/AddNavItem'
class Main extends Component {
state = {
items: [
{id: 1, name: 'Услуги', link: 'services'},
{id: 2, name: 'Цены', link: 'prices'},
{id: 3, name: 'Как это работает?', link: 'works'},
]
}
addNavItem = (item) => {
this.setState((state) => {
let newItems = [...state.items];
newItems.unshift(item)
console.log(newItems);
return {
items: newItems
}
});
}
render() {
return (
<div>
<Navbar items={ this.state.items }/>
<AddNavItem addNavItem={ this.addNavItem }/>
</div>
);
}
}
export default Main;
問題是即使在addNavItem
觸發后,我也總是會得到帶有3個初始obj的舊數組。 <Navbar />
仍然獲得具有3個元素的數組。 我已經閱讀了有關異步setState的信息,並按照文檔https://reactjs.org/docs/faq-state.html中的說明進行了操作。
UPD:我更改了代碼(取消移位)以返回數組,而不是數組的長度。 控制台日志顯示我得到了4個obj的新數組
UPD:我所有組件的完整代碼:
導航欄
import React, { Component } from 'react';
import NavItem from './NavItem';
class Navbar extends Component {
state = {
items: this.props.items,
}
render() {
return (
<div className="centered navbar grey">
<h2>MyReact</h2>
<ul>
<NavItem items={ this.state.items }/>
</ul>
</div>
);
};
}
export default Navbar;
NavItem:
import React from 'react';
const NavItem = ({ items }) => {
const menuItemList = items.map((item) => {
return (
<li key={item.id}>
{ item.name }
</li>
);
})
return (
<div>
{ menuItemList }
</div>
)
}
export default NavItem;
AddNavItem:
import React, { Component } from 'react';
class AddNavItem extends Component {
state = {
id: Math.random(),
name: null,
link: null
}
handleInput = (e) => {
this.setState({
[e.target.id]: e.target.value,
});
}
handleSubmit = (e) => {
e.preventDefault();
this.props.addNavItem(this.state);
}
render() {
return (
<div className="centered flex-column-centered">
<form onSubmit={ this.handleSubmit }>
<h4 className="labelField">Название раздела:</h4>
<input
className="inputField"
type="text"
id="name"
placeholder="укажите название"
onChange={ this.handleInput } />
<h4 className="labelField">URL:</h4>
<input
className="inputField"
type="text"
id="link"
placeholder="укажите ссылку"
onChange={ this.handleInput } />
<button className="submitBtn">Добавить</button>
</form>
</div>
);
}
}
export default AddNavItem;
let arr = [3,4,5] console.log(arr.unshift(3,5))
addNavItem = (item) => {
let newItems = [...this.state.items];
newItems.unshift(item)
this.setState({
items: newItems
}
});
}
現在,您要更新數組並將元素添加到數組的開頭,我認為這是您想要的,這就是您選擇升檔的原因。 然后將狀態設置為等於您擁有的更新數組。
unshift()方法將一個或多個元素添加到數組的開頭,並返回數組的新長度。
因此,當您嘗試使用此方法更改狀態時,它會返回數組的長度,而不是您嘗試將狀態更新為的新數組。 最重要的是,此方法是可變的,因為您正在修改原始數組,而不是返回它的新副本。 我建議您更改代碼以使用array.prototype.concat()方法代替,因為它可以使您的狀態保持不變,因為它返回新數組而不是修改原始數組。
嘗試將您的方法更改為此。
addNavItem = (item) => {
this.setState({ items: this.state.items.concat(item) });
}
編輯:
如果使用的是es6,則可以使用傳播語法 ,該語法還返回數組的新副本。
addNavItem = (item) => {
this.setState({ items: [...this.state.items, item] });
}
編輯2:在Navbar組件中,您將this.props.items設置為在初始化時聲明,然后在this.props.items更改時不更新狀態。
您不需要此組件的狀態,我可以將NavBar組件更改為如下所示:
import React from 'react';
import NavItem from './NavItem';
const Navbar = (props) => {
return (
<div className="centered navbar grey">
<h2>MyReact</h2>
<ul>
<NavItem items={ props.items }/>
</ul>
</div>
);
}
export default Navbar;
編輯3:
如果要將項目保持在NavBar組件中的內部狀態,則需要注意是否對該組件上的item道具進行了更新。
import React, { Component } from 'react';
import NavItem from './NavItem';
class Navbar extends Component {
state = {
items: this.props.items,
}
componentDidUpdate(prevProps) {
if (this.props.items!== prevProps.items) {
this.setState({ items: this.props.items });
}
}
render() {
return (
<div className="centered navbar grey">
<h2>MyReact</h2>
<ul>
<NavItem items={ this.state.items }/>
</ul>
</div>
);
};
}
export default Navbar;
addNavItem = (item) => {
this.setState((prevState) => {items: [...prevState.items, item]})
}
這應該工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.