使用下拉反应带更改状态

Posted

技术标签:

【中文标题】使用下拉反应带更改状态【英文标题】:Change state with dropdown reactstrap 【发布时间】:2019-12-13 09:30:47 【问题描述】:

我正在使用 reactstrap 创建一个下拉菜单,并且我想在选择下拉菜单的其他项目时更改 dropDownValueNav 的值。

问题出在我的onClick 函数内部。在那里我设置了我的新值的状态,但它不会立即改变;只有在第二次点击时才会这样做。

我该如何解决这个问题?

这是我的代码:

import React,  PureComponent  from 'react';
import 
  Row,
  Card,
  Nav,
  Navbar,
  NavItem,
  UncontrolledDropdown,
  DropdownToggle,
  DropdownItem,
  DropdownMenu,
 from 'reactstrap';
import  withTranslation  from 'react-i18next';
import PropTypes from 'prop-types';
import DownIcon from 'mdi-react/ChevronDownIcon';
import 
  Link,
  NavLink,
 from 'react-router-dom';


class Menu extends PureComponent 
  static propTypes = 
    t: PropTypes.func.isRequired,
  ;

  constructor(props) 
    super(props);
    this.state = 
      dropDownValueNav: 'Home,
      dropdownOpen: false,
    ;
  

  toggle = () => 
    const  dropdownOpen  = this.state;
    this.setState(
      dropdownOpen: !dropdownOpen,
    );
    console.log(this.state.dropdownOpen)
  ;

  changeValueSecondary = (e) => 
    this.setState( dropDownValueNav: e.currentTarget.textContent );
    console.log(e.currentTarget.textContent);
    console.log('state', this.state.dropDownValueNav);
  ;

  render() 
    const  t  = this.props;
    const  dropdownOpen, dropDownValueNav  = this.state;

    return (
      <Card inverse>

        <Row>
          <div className="col-auto">

            <Navbar>
              <Nav className="text_lg" navbar>
                <UncontrolledDropdown toggle=this.toggle isOpen=dropdownOpen>
                  <DropdownToggle nav>
                    dropDownValueNav
                  </DropdownToggle>

                  <DropdownMenu>
                    <DropdownItem onClick=this.changeValueSecondary>
                      <Link to="/react">react</Link>
                    </DropdownItem>

                    <DropdownItem onClick=this.changeValueSecondary>
                      <Link to="/html">html</Link>
                    </DropdownItem>

                    <DropdownItem onClick=this.changeValueSecondary>
                      <Link to="/css">css</Link>
                    </DropdownItem>
                  </DropdownMenu>
                </UncontrolledDropdown>
              </Nav>
            </Navbar>

        </Row>

      </Card>
    );
  


export default withTranslation('common')(Menu);

【问题讨论】:

因为 setState 是异步的,你的 console.log 仍然会显示之前的状态。要访问新状态,请使用秒 setState 参数回调。 @Domino987 你能给我看一个例子吗? 它在文档中:this.setState((state, props) => return counter: state.counter + props.step; , () => console.log(this. state)// 这是新的状态); 【参考方案1】:

setState() 并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用 setState() 之后立即读取 this.state 是一个潜在的陷阱。而是使用 componentDidUpdate 或 setState 回调 (setState(updater, callback))。

这样做以查看控制台更新状态:

toggle = () => 
    const  dropdownOpen  = this.state;
    this.setState(
      dropdownOpen: !dropdownOpen,
    , () => console.log(this.state.dropdownOpen))
;

changeValueSecondary = (e) => 
    this.setState(
        dropDownValueNav: e.currentTarget.textContent ,
       () => console.log('state', this.state.dropDownValueNav)
    );
    console.log(e.currentTarget.textContent);

;

【讨论】:

【参考方案2】:

setState() 异步工作,因此出于性能目的,它将对状态的更新批处理在一起。More Details

要克服这种竞争条件,您可以通过几种方式编写此代码。

    您可以使用回调函数调用 console.log(),它会显示更新后的选项。

    您可以尝试使用 prevState 作为 setState() 的参数,并可以使用它来更新状态。

    您还可以编写可以在回调中调用以更新状态的更新程序函数。

所有选项的示例。

toggle = () => 
    this.setState(
      this.state.dropdownOpen: !this.state.dropdownOpen, 
        () => console.log(this.state.dropdownOpen)
    )
;

changeValueSecondary = (e) => 
    this.setState( 
        this.state.dropDownValueNav: e.currentTarget.textContent,
            () => console.log(this.state.dropDownValueNav)
    );
;

toggle = () => 
this.setState((prevState) => (
    dropdownOpen: !prevState.dropdownOpen
    ));
;

changeValueSecondary = (e) => 
    this.setState( 
        this.state.dropDownValueNav: e.currentTarget.textContent,
            () => doSomeThingWithTheUpdatedState();
    );
;

doSomeThingWithTheUpdatedState = () => 
    //Use the new value of the state.dropDownValueNav

同样对于高级应用程序,您可以使用要调用的化简器,它最终会在您使用它们之前更新状态。

【讨论】:

以上是关于使用下拉反应带更改状态的主要内容,如果未能解决你的问题,请参考以下文章

我正在将我的颤振应用程序的状态管理更改为 getx,我遇到了在下拉选择后更改应用程序状态的问题

状态更改时 React 组件未更新

如果下拉列表使用 Hooks 和 useState 选择了值,如何更新状态

Android文本输入布局更改选定状态颜色

如何使用react js在select中设置默认值

下拉打开时如何使链接处于活动状态?