我正在尝试更新组件的状态,但无法正常工作。我有主页容器组件=>嵌套的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;
答案 0 :(得分:0)
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
}
});
}
现在,您正在更新数组并将元素添加到数组的开头,我认为这是您想要的,这就是为什么您选择升档。然后将状态设置为与拥有的更新数组相等。
答案 1 :(得分:0)
unshift()方法将一个或多个元素添加到数组的开头,并返回数组的新长度。
因此,当您尝试使用此方法更改状态时,它会返回数组的长度,而不是要尝试将状态更新为的新数组。最重要的是,此方法是 mutable (可变的),因为您正在修改原始数组而不是返回它的新副本。我建议更改您的代码以使用array.prototype.concat()方法,因为它使状态保持不可变,因为它返回一个新数组而不是修改原始数组。
尝试将您的方法更改为此。
addNavItem = (item) => {
this.setState({ items: this.state.items.concat(item) });
}
编辑:
如果您使用的是es6,则可以使用spread syntax,它还会返回该数组的新副本。
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组件的内部状态,则需要注意是否对该组件上的道具进行了更新。
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;
答案 2 :(得分:0)
addNavItem = (item) => {
this.setState((prevState) => {items: [...prevState.items, item]})
}
这应该有效。