React JS不会在状态突变时重新呈现地图

时间:2018-08-22 08:19:43

标签: reactjs list render

我目前正在学习使用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;

1 个答案:

答案 0 :(得分:0)

NavBarHeaderItem构造函数中,您将所有道具复制到状态,然后在render()中使用状态,但是该构造函数将仅被调用一次-不会在NavBarHeaderItem的每个渲染上调用。这意味着状态在组件的整个生命周期中都将保持不变,并且可以解释您所看到的行为。

您应该更改NavBarHeaderItem.render()以使用props中的数据,而不要使用state-将this.state.selected的所有实例更改为this.props.selected,等等。