Ami*_*aie 3 javascript setstate reactjs
我知道有些反应但我陷入了一种奇怪的境地.
我有两个输入和一个按钮,当两个输入都不为空时,应该启用该按钮.所以,我为每个输入值使用了一个state属性,还有一个属性告诉我两个输入是否都有值:
this.state = {
title: '',
time :'',
enabled : false
}
Run Code Online (Sandbox Code Playgroud)
我也有一个onChange为每个输入相应地设置状态:
<input type="text" id="time" name="time" onChange={this.onChange.bind(this)} value={this.state.time}></input>
<input type="text" id="title" name="title" onChange={this.onChange.bind(this)} value={this.state.title}></input>
Run Code Online (Sandbox Code Playgroud)
而onChange就是这样的
onChange(e){
this.setState({
[e.target.id] : e.target.value,
enabled : ( (this.state.title==='' || this.state.time==='' ) ? false : true)
});
}
Run Code Online (Sandbox Code Playgroud)
问题是setState查看先前的状态,并且启用总是落后一步,所以如果我先输入X,第二次输入Y,那么启用的结果仍为false.
我设法通过使用setTimeout并在其中使用第二行来解决它,但它看起来不对我.
onChange(e){
this.setState({
[e.target.id] : e.target.value,
});
setTimeout(() => {
this.setState({
enabled : ( (this.state.title==='' || this.state.time==='' ) ? false : true)
});
}, 0);
}
Run Code Online (Sandbox Code Playgroud)
更好的解决方案?
有更好的解决方案吗?
您可以通过3种解决方案来实现,只需选择一种
componentDidUpdate()class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "",
time: "",
enabled: false
};
}
onChange(e) {
this.setState({
[e.target.id]: e.target.value
});
}
componentDidUpdate(prevProps, prevState) {
if (
prevState.time !== this.state.time ||
prevState.title !== this.state.title
) {
if (this.state.title && this.state.time) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
}
render() {
return (
<React.Fragment>
<input
type="text"
id="time"
name="time"
onChange={this.onChange.bind(this)}
value={this.state.time}
/>
<input
type="text"
id="title"
name="title"
onChange={this.onChange.bind(this)}
value={this.state.title}
/>
<button disabled={!this.state.enabled}>Button</button>
</React.Fragment>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
setState回调class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "",
time: "",
enabled: false
};
}
onChange(e) {
this.setState({[e.target.id]: e.target.value},
() => {
if (this.state.title && this.state.time) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
);
}
render() {
return (
<React.Fragment>
<input
type="text"
id="time"
name="time"
onChange={this.onChange.bind(this)}
value={this.state.time}
/>
<input
type="text"
id="title"
name="title"
onChange={this.onChange.bind(this)}
value={this.state.title}
/>
<button disabled={!this.state.enabled}>Button</button>
</React.Fragment>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
enabled根据title和计算timeclass App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: "",
time: ""
};
}
onChange(e) {
this.setState({
[e.target.id]: e.target.value
});
}
render() {
const enabled = this.state.time && this.state.title;
return (
<React.Fragment>
<input
type="text"
id="time"
name="time"
onChange={this.onChange.bind(this)}
value={this.state.time}
/>
<input
type="text"
id="title"
name="title"
onChange={this.onChange.bind(this)}
value={this.state.title}
/>
<button disabled={!enabled}>Button</button>
</React.Fragment>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
首先,您不需要为启用状态维护状态,因为它可以从其他状态值派生,并且可以直接在渲染中完成
onChange(e){
this.setState({
[e.target.id] : e.target.value,
});
}
render() {
const enabled = this.state.title !== "" && this.state.time !== "";
return (
<div>
<input type="text" id="time" name="time" onChange={this.onChange.bind(this)} value={this.state.time}></input>
<input type="text" id="title" name="title" onChange={this.onChange.bind(this)} value={this.state.title}></input>
<button disabled={!enabled}>Button</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)