使用下拉反应带更改状态
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,我遇到了在下拉选择后更改应用程序状态的问题