我想问一下当我做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
答案 0 :(得分:100)
您的状态需要一些时间进行变异,并且由于console.log(this.state.boardAddModalShow)
在状态变异之前执行,因此您将前一个值作为输出。所以你需要在回调中写入控制台到setState函数
openAddBoardModal(){
this.setState({ boardAddModalShow: true }, function () {
console.log(this.state.boardAddModalShow);
});
}
setState
是异步的。这意味着你不能在一行上调用setState并假设下一个状态已经改变了。
根据 React docs
setState()
不会立即改变this.state
但会创建一个 待定状态转换。在调用此文件后访问this.state
方法可以返回现有值。没有 保证调用setState和调用的同步操作 为获得业绩增长而受到批评。
为什么他们会使setState异步
这是因为setState改变了状态并导致重新渲染。这个 可能是一个昂贵的操作,使它同步可能会离开 浏览器没有响应。
因此,setState调用是异步的,也是为了更好的批处理 用户体验和性能。
答案 1 :(得分:15)
幸运的是,setState进行了回调。这是我们获取更新状态的地方。考虑这个例子。
this.setState(
{ name: "Mustkeom" },
() => {
console.log(this.state.name) // Mustkeom
}
);
因此,当回调触发时,this.state是更新后的状态。您可以在回调中获取突变/更新的数据。
答案 2 :(得分:9)
由于setSatate是异步函数,因此您需要像这样将状态作为回调进行控制台。
openAddBoardModal(){
this.setState({ boardAddModalShow: true }, () => {
console.log(this.state.boardAddModalShow)
});
}
答案 3 :(得分:4)
setState()
并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState()
之后立即读取this.state是潜在的陷阱。相反,请使用componentDidUpdate
或setState
回调(setState(updater, callback)
),可以保证在应用更新后会触发二者之一。如果需要基于先前的状态来设置状态,请阅读以下有关updater参数的信息。
setState()
返回false,否则 shouldComponentUpdate()
将始终导致重新渲染。如果正在使用可变对象,并且无法在shouldComponentUpdate()
中实现条件渲染逻辑,那么仅当新状态不同于先前状态时调用setState()
才能避免不必要的重新渲染。
第一个参数是带有签名的更新程序函数
(state, props) => stateChange
state
是在应用更改时对组件状态的引用。它不应该直接突变。相反,更改应通过根据状态和道具的输入来构建新对象来表示。例如,假设我们想通过props.step来增加state的值:
this.setState((state, props) => {
return {counter: state.counter + props.step};
});
答案 4 :(得分:3)
此回调确实很混乱。只需使用async await代替:
async openAddBoardModal(){
await this.setState({ boardAddModalShow: true });
console.log(this.state.boardAddModalShow);
}
答案 5 :(得分:2)
如果您想跟踪状态是否正在更新,那么做同一件事的另一种方法是
_stateUpdated(){
console.log(this.state. boardAddModalShow);
}
openAddBoardModal(){
this.setState(
{boardAddModalShow: true},
this._stateUpdated.bind(this)
);
}
这样,您每次尝试更新状态进行调试时都可以调用方法“ _stateUpdated”。
答案 6 :(得分:2)
对于尝试使用钩子进行此操作的任何人,您都需要copy body body_clone
parse-as-json body 1
parse-as-json body_clone 2
set-column final_result !body_clone_field ? body_field : body_clone_field
。
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>
</>
}
答案 7 :(得分:1)
是,因为setState是异步函数。写入设置状态后立即设置状态的最佳方法是使用Object.assign,如下所示: 例如,例如,您要将isValid属性设置为true,请执行以下操作
Object.assign(this.state,{isValid:true})
您可以在编写此行后立即访问更新状态。
答案 8 :(得分:0)
setState()
是异步的。验证状态是否正在更新的最佳方法是在componentDidUpdate()
中,而不要在console.log(this.state.boardAddModalShow)
之后放置this.setState({ boardAddModalShow: true })
。
将setState()视为请求而不是立即命令来更新组件。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React无法保证状态更改会立即应用
答案 9 :(得分:0)
this.setState({
isMonthFee: !this.state.isMonthFee,
}, () => {
console.log(this.state.isMonthFee);
})
答案 10 :(得分:0)
反应不能保证状态更改立即生效。 这使得在调用setState()之后立即读取this.state可能是
pitfall
,并且由于existing
的性质,可能会返回async
值。 相反,请使用componentDidUpdate
或在setState操作成功后立即执行的setState
回调。通常,我们建议使用componentDidUpdate()
代替此类逻辑。
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
constructor() {
super();
this.state = {
counter: 1
};
}
componentDidUpdate() {
console.log("componentDidUpdate fired");
console.log("STATE", this.state);
}
updateState = () => {
this.setState(
(state, props) => {
return { counter: state.counter + 1 };
});
};
render() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button onClick={this.updateState}>Update State</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
答案 11 :(得分:0)
setState是一个异步函数,因此您可能需要将其用作
this.setState({key:value},()=>{ callYourFunction(this.state.key) });
答案 12 :(得分:0)
当我运行代码并在控制台上检查我的输出时,显示未定义。 在四处搜寻并找到对我有用的东西之后。
componentDidUpdate(){}
我在构造函数()之后的代码中添加了此方法。 看看React Native工作流程的生命周期。
答案 13 :(得分:0)
openAddBoardModal=async()=>{
await this.setState({ boardAddModalShow: true });
console.log(this.state.boardAddModalShow);
}
答案 14 :(得分:0)
将setState()视为请求,而不是直接命令 更新组件。为了获得更好的感知性能,React可能会 延迟它,然后一次通过更新几个组件。反应 不保证状态更改会立即应用。
检查this以获得更多信息。
因此,在您的情况下,您已发送请求以更新状态。 React需要一段时间才能做出响应。因此,如果您立即尝试控制状态,则将获得旧值。
答案 15 :(得分:0)
尽管有很多不错的答案,但如果有人在此页面上搜索 _Decimal64
的替代方案以实现应根据用户输入打开或关闭的 UI 组件(如导航抽屉),则此答案会有所帮助。< /p>
虽然 useState
看起来很方便,但状态不会立即设置,因此,您的网站或应用程序看起来很慢...如果您的页面足够大,react 将需要很长时间来计算所有内容应在状态更改时更新...
我的建议是,当您希望 UI 立即更改以响应用户操作时,使用 refs 并直接操作 DOM。
为了这个目的而使用状态对于反应来说真的是一个坏主意。