setState不是永久的

时间:2019-04-03 06:28:50

标签: javascript reactjs render setstate

我正在尝试创建一个具有可折叠选项的菜单。

下面是我的代码:

 GridView.builder(
      shrinkWrap: true,
      itemCount: itemDataList.length,
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2,childAspectRatio: 0.6),
      itemBuilder: (BuildContext context, int index){
        return Card(
          elevation: 6.0,
          child: Column(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Center(
                child: Text(itemDataList[index].title),
              ),

              displayItem("id ", itemDataList[index].id),
              displayItem("price ", itemDataList[index].price.toString()),
              ListView.builder
                (
                  physics: NeverScrollableScrollPhysics(),
                  shrinkWrap: true,
                  itemCount: itemDataList[index].services.length,
                  itemBuilder: (BuildContext ctxt, int indx) {
                    return new Column(
                      mainAxisSize: MainAxisSize.max,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Divider(
                          height: 2,
                          color: Colors.black,
                        ),
                        displayItem("_Id", itemDataList[index].services[indx].sId),
                        displayItem("Service Id", itemDataList[index].services[indx].serviceId),
                        displayItem("Service name", itemDataList[index].services[indx].name),
                      ],
                    );
                  }
              ),
            ],
          ),
        );
      },
    ),
  )



Widget displayItem(String key, String value){
    return Padding(
      padding: const EdgeInsets.all(2.0),
      child: Text('$key : $value', style: TextStyle(fontSize: 11),),
    );
  }

当我在render()方法中打印出export default class CRSideMenu extends React.Component { constructor(props) { super(props); this.state = { fprActive: true }; autoBind(this); } toggleFPR() { console.log('Setting fprActive from ', this.state.fprActive, ' to ', !this.state.fprActive); this.setState({ fprActive: !this.state.fprActive }); } render() { console.log('render', this.state.fprActive); return ( <ul className='list-group list-group-nav'> <li> <a href='#' className={classnames('list-group-item', this.state.fprActive && 'active', 'has-subnav')} onClick={this.toggleFPR} > FPR </a> <ul className='list-group list-group-nav'> <li> <a href='' className='list-group-item'>FR</a> </li> </ul> </li> </ul> ); } } 时,会看到以下内容:

  • 将fprActive从true设置为false
  • 渲染为假
  • 渲染为真

当我只单击一次时,为什么我的fprActive会自动倒退为“ true”?

1 个答案:

答案 0 :(得分:4)

我目前无法复制该问题,但症状是单击锚点时您的页面正在刷新,因为您没有阻止默认操作。在收到的事件对象上toggleFPR调用preventDefault

toggleFPR(event) {
//        ^^^^^ ------------ ***
  event.preventDefault(); // ***
  console.log('Setting fprActive from ', this.state.fprActive, ' to ', !this.state.fprActive);
  this.setState({
    fprActive: !this.state.fprActive
  });
}

另外:您在此处破坏the fundamental React rules之一:

console.log('Setting fprActive from ', this.state.fprActive, ' to ', !this.state.fprActive);
this.setState({
  fprActive: !this.state.fprActive
});

根据现有状态设置状态时,您必须使用回调版本,而不是将对象传递到的版本:

this.setState(({fprActive}) => {
  console.log('Setting fprActive from ', fprActive, ' to ', !fprActive);
  return {fprActive: !fprActive};
});

如果不这样做,它将在大多数时间都有效,并且有时会以难以诊断的方式失败。