我目前正在学习使用React开发SPA并遇到一些问题。 我的应用程序当前包含两个组件:第一个组件称为“ NavBarHeader” ,它代表一个包含三个项目的导航栏。此导航中的每个项目都称为“ NavBarHeaderItem” ,并由一个单独的组件表示。最初,选择了“数据”项并引用了CSS 选择器“ navbar-item-active”,以使用其他背景色显示当前选定的项目。这是通过在render()函数返回其元素之前呈现一个列表来完成的。理想情况下,如果用户选择了每个项目,则应向其父项(NavBarHeader)发送消息。但是,每次 NavBarHeader会更新所选项目,即使状态已被React正确更改,也不会发生任何变化。
NavBarHeader.js
import React,{Component} from 'react';
import './NavBarHeader.css';
import NavBarHeaderItem from './NavBarHeaderItem.js';
import folder from './res/folder.svg';
import manager from './res/agenda.svg';
import encyclopedia from './res/encyclopedia.svg'
class NavBarHeader extends Component
{
constructor(props)
{
super(props);
this.setSelectedItem = this.setSelectedItem.bind(this);
this.state = {
selectedItem: "Data",
// Descriptors contains a text description and an image
descriptors:[{text:"Data",image:folder},{text:"Tags",image:manager},{text:"Encyclopedia",image:encyclopedia}]
};
}
setSelectedItem(updatedItem)
{
// Change the selected item of the NavBar
this.setState({selectedItem:updatedItem});
}
render()
{
//Map descriptors to the NavBarHeaderItems
var currentDescriptors = this.state.descriptors
var currentlySelectedItem = this.state.selectedItem;
console.log("["+currentDescriptors+","+currentlySelectedItem+"]");
var NavBarItems = currentDescriptors.map((descriptor) =>
<NavBarHeaderItem key={this.state.descriptors.indexOf(descriptor)}
text={descriptor.text} image={descriptor.image}
selected={(currentlySelectedItem === descriptor.text) ? true : false}
onSelect={this.setSelectedItem}
/>);
return (
<ul className ="navbar-header">
{NavBarItems}
</ul>
)
}
}
export default NavBarHeader;
NavBarHeaderItem.js
import React,{Component} from 'react';
import './NavBarHeader.css';
class NavBarHeaderItem extends Component
{
constructor(props)
{
super(props);
// Each NavBarHeaderItem has an icon and a descriptive text
this.state = {
text: props.text,
image: props.image,
selected: this.props.selected,
};
// Bind methods to the Component
this.handleClick = this.handleClick.bind(this);
}
handleClick()
{
console.log("Click!");
this.props.onSelect(this.state.text);
}
render()
{
console.log("["+this.state.text+","+this.state.selected+"]");
// Normal item which will be rendered if
const normalItem = (
<li className="navbar-item" onClick={this.handleClick}>
<img className="navbar-item-image" src={this.state.image} alt=""/>
<a className="navbar-item-text">{this.state.text}</a>
</li>
);
// Selected items have a different appearance
const selectedItem=(
<li className="navbar-item-active" onClick={this.handleClick}>
<img className="navbar-item-image" src={this.state.image} alt=""/>
<a className="navbar-item-text">{this.state.text}</a>
</li>
);
if(this.state.selected)
{
return (
selectedItem
)
} else if(!this.state.selected)
{
return (
normalItem
)
}
}
}
export default NavBarHeaderItem;
答案 0 :(得分:0)
在NavBarHeaderItem
构造函数中,您将所有道具复制到状态,然后在render()
中使用状态,但是该构造函数将仅被调用一次-不会在NavBarHeaderItem
的每个渲染上调用。这意味着状态在组件的整个生命周期中都将保持不变,并且可以解释您所看到的行为。
您应该更改NavBarHeaderItem.render()
以使用props
中的数据,而不要使用state
-将this.state.selected
的所有实例更改为this.props.selected
,等等。