Syd*_*ria 72 javascript ecmascript-6 reactjs
我想问一下当我做onclick事件时为什么我的状态没有改变.我刚才搜索过我需要在构造函数中绑定onclick函数,但状态仍未更新.这是我的代码:
import React from 'react';
import Grid from 'react-bootstrap/lib/Grid';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
import BoardAddModal from 'components/board/BoardAddModal.jsx';
import style from 'styles/boarditem.css';
class BoardAdd extends React.Component {
constructor(props){
super(props);
this.state = {
boardAddModalShow: false
}
this.openAddBoardModal = this.openAddBoardModal.bind(this);
}
openAddBoardModal(){
this.setState({ boardAddModalShow: true });
// After setting a new state it still return a false value
console.log(this.state.boardAddModalShow);
}
render() {
return (
<Col lg={3}>
<a href="javascript:;" className={style.boardItemAdd} onClick={this.openAddBoardModal}>
<div className={[style.boardItemContainer,style.boardItemGray].join(' ')}>
Create New Board
</div>
</a>
</Col>
)
}
}
export default BoardAdd
Run Code Online (Sandbox Code Playgroud)
Shu*_*tri 121
你的状态需要一些时间来改变,并且自从console.log(this.state.boardAddModalShow)状态变异之前执行,你得到前一个值作为输出.所以你需要在回调到setState函数的过程中编写控制台
openAddBoardModal(){
this.setState({ boardAddModalShow: true }, function () {
console.log(this.state.boardAddModalShow);
});
}
Run Code Online (Sandbox Code Playgroud)
setState是异步的.这意味着你不能在一行上调用setState并假设状态在下一行已经改变.
setState()不会立即变异this.state但会创建待定状态转换.this.state调用此方法后访问可能会返回现有值.无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升.
为什么他们会使setState异步
这是因为setState改变了状态并导致重新渲染.这可能是一项昂贵的操作,并使其同步可能会使浏览器无响应.
因此,setState调用是异步的,也可以是批处理的,以获得更好的UI体验和性能.
Amj*_*d K 23
幸运的是,setState需要回调.这是我们获得更新状态的地方.考虑这个例子.
this.setState(
{ name: "Mustkeom" },
() => { //callback
console.log(this.state.name) // Mustkeom
}
);
Run Code Online (Sandbox Code Playgroud)
所以当回调触发时,this.state是更新状态.您可以在回调中获得变异/更新的数据.
Adn*_*hah 11
由于setSatate是一个异步函数,因此您需要将状态控制为这样的回调.
openAddBoardModal(){
this.setState({ boardAddModalShow: true }, () => {
console.log(this.state.boardAddModalShow)
});
}
Run Code Online (Sandbox Code Playgroud)
Spo*_*ck 9
这个回调真的很混乱。只需使用async await代替:
async openAddBoardModal(){
await this.setState({ boardAddModalShow: true });
console.log(this.state.boardAddModalShow);
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以按以下方式管理代码。
openAddBoardModal(){
this.setState({ boardAddModalShow: true }, () => {
console.log(this.state.boardAddModalShow);
});
}
Run Code Online (Sandbox Code Playgroud)
对于任何试图用钩子来做到这一点的人,你需要useEffect.
function App() {
const [x, setX] = useState(5)
const [y, setY] = useState(15)
console.log("Element is rendered:", x, y)
// setting y does not trigger the effect
// the second argument is an array of dependencies
useEffect(() => console.log("re-render because x changed:", x), [x])
function handleXClick() {
console.log("x before setting:", x)
setX(10)
console.log("x in *line* after setting:", x)
}
return <>
<div> x is {x}. </div>
<button onClick={handleXClick}> set x to 10</button>
<div> y is {y}. </div>
<button onClick={() => setY(20)}> set y to 20</button>
</>
}
Run Code Online (Sandbox Code Playgroud)
输出:
Element is rendered: 5 15
re-render because x changed: 5
(press x button)
x before setting: 5
x in *line* after setting: 5
Element is rendered: 10 15
re-render because x changed: 10
(press y button)
Element is rendered: 10 20
Run Code Online (Sandbox Code Playgroud)
小智 5
setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState()潜在陷阱之后立即阅读this.state 。而是使用componentDidUpdate或setState回调(setState(updater, callback)),保证在应用更新后都会触发两者。如果需要基于先前的状态来设置状态,请阅读以下有关updater参数的信息。
setState()除非shouldComponentUpdate()返回false,否则将始终导致重新渲染。如果正在使用可变对象,并且无法在中实现条件渲染逻辑shouldComponentUpdate(),则setState()仅在新状态与先前状态不同时进行调用才能避免不必要的重新渲染。
第一个参数是带有签名的updater函数:
(state, props) => stateChange
Run Code Online (Sandbox Code Playgroud)
state是在应用更改时对组件状态的引用。它不应该直接突变。相反,更改应通过根据状态和道具的输入来构建新对象来表示。例如,假设我们想通过props.step增加state的值:
this.setState((state, props) => {
return {counter: state.counter + props.step};
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
37796 次 |
| 最近记录: |