更改React组件的顺序仅在第二次单击后触发重新渲染

时间:2018-12-13 19:40:00

标签: javascript reactjs

因此,我正在将数组映射到列表组以显示项目列表。我希望能够按项目的任何属性对该列表进行排序。我能够很容易地对数组求助,并且我有一个Reactstrap下拉列表来触发排序,并且数组可以正确排序,甚至可以正确地在组件中更新。但是,该组件不会重新渲染。但是,如果我再次单击该按钮以打开下拉列表,则组件将重新呈现。我很困惑。有什么想法吗?

容器组件文件中用于排序的函数(使用另一个外部实用程序函数,同样可以正常工作):

  select(event) {
    this.setState({
      sortBy: event.target.innerText
    }, function () {
        const propName = this.state.sortBy.toLowerCase();
        this.state.dives.sort(Utilities.sortByParam(propName));
    });
  }

这是演示组件:

const DiveList = (props) => {
  const {
    dives,
    toggle,
    select,
    isOpen,
  } = props;
  console.log('dives: ', dives);
  return (
    <div>
      <h3>My Dives 
        <Dropdown size="sm" className="float-right" isOpen={isOpen} toggle={toggle}>
          <DropdownToggle caret>
            Sort By
          </DropdownToggle>
          <DropdownMenu right>
            <DropdownItem onClick={select}>Number</DropdownItem>
            <DropdownItem onClick={select}>Location</DropdownItem>
            <DropdownItem onClick={select}>Date</DropdownItem>
          </DropdownMenu>
        </Dropdown>
      </h3>
      {dives.length > 0 &&
        <div>
          <ListGroup>
            {dives.map((dive) => (
              <ListGroupItem key={`dive-${dive.number}`}>
                <Link to={`/divedetails/${dive.number}`}>
                  <div>
                    <span>Dive #{dive.number}</span> 
                    <span className="float-right">{dive.date}</span>
                  </div>
                  <div className="float-left">{dive.location}</div>
                </Link>
              </ListGroupItem>
            ))}
          </ListGroup>
        </div>
      }
      {dives.length <= 0 && 
        <h5>You don't have any dives logged yet.  Time to get wet!!!</h5>
      }
    </div>
  );
};

export default DiveList;

同样,当在下拉列表中选择(单击)按钮时,控制台日志“ dives”会立即更新阵列,但是ListGroup组件不会重新呈现。

如果再次单击“排序依据”按钮(不是菜单按钮之一,而是切换按钮),则组件将刷新。

帮助...

1 个答案:

答案 0 :(得分:1)

问题在于您是a)在setState回调中排序,并且b)您的排序是对dives进行了突变,而不是通过{{ 1}}。这是因为如果state.dives直接发生突变,则不会调用setState-仅当调用render时才会调用。相反,您可以在state函数中执行排序,并在单个setState调用中设置selectsortBy

dives