reactjs - 单击两次时 React 会更新状态

标签 reactjs

由于 React 存在问题,无法立即在 console.log 上更新状态,我必须单击两次提交按钮才能让 console.log 显示更新后的状态

我检查了这一点,但我不认为这可能是问题

React: state not updating on first click

工作演示,检查控制台

https://codesandbox.io/s/l499j0p5vm?fontsize=14

这是我所拥有的

App.js

import React, {Component} from 'react';
import Navbar from './components/Navbar';
import {withStyles} from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';
import logo from './logo.svg';
import {Typography, Button} from '@material-ui/core';
import Footer from './components/Footer';
import Emoji from './components/Emoji';
import TextField from '@material-ui/core/TextField';
import EmojiPicker from 'emoji-picker-react';
import JSEMOJI from 'emoji-js';
import Icon from '@material-ui/core/Icon';
let jsemoji = new JSEMOJI();
// set the style to emojione (default - apple)
jsemoji.img_set = 'emojione';
// set the storage location for all emojis
jsemoji.img_sets.emojione.path = 'https://cdn.jsdelivr.net/emojione/assets/3.0/png/32/';
// some more settings...
jsemoji.supports_css = false;
jsemoji.allow_native = true;
jsemoji.replace_mode = 'unified'
const styles = theme => ({
    shadows: ["none"],
    spacing: 8,
    root: {
        flexGrow: 1,
        minHeight: '800px',
        width: '100%',
        position: 'relative'
    },
    paper: {
        padding: theme.spacing.unit * 2,
        textAlign: 'left',
        width: '500px',
        color: theme.palette.text.secondary
    },
    textField: {
        width: '400px'
    },
    myitem: {
        margin: '40px'
    },
    emoji: {
        margin: '40px'
    },
    emojiButton: {
        margin: '20px 0px'
    },
    cancel: {
        margin: '20px 0px'
    }
});
class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            emoji: '',
            text: '',
            items: [],
            emojiToggle: false
        }
    }
    onChange = (e) => {
        e.preventDefault()
        this.setState({text: e.target.value});
    }
    handleClick = (n, e) => {
        let emoji = jsemoji.replace_colons(`:${e.name}:`);

        this.setState({
            text: this.state.text + emoji,
        });
        // console.log(this.state.items)
    }
    handleButton = (e) => {
        e.preventDefault();
        if(!this.state.emojiToggle){
          this.setState({emojiToggle: true})
        }
        else{
          this.setState({emojiToggle: false})

        }

    }

    onSubmit = (e) => {
      e.preventDefault();
      this.setState({
        text: this.state.text,
        items: [this.state.text]
      })

      console.log(this.state.items) // have to click twice to see the updated state

    }


    render() {
        const {classes} = this.props;
        return (
            <div className={classes.root}>
                <Navbar/>
                <Grid container spacing={12}>
                    <Grid item sm={6} className={classes.myitem}>
                        <Paper className={classes.paper}>
                            <Typography variant="h2" component="h2">
                                Insert An Emoji
                            </Typography>
                          {/* Begin Form */}
                          <form>
                            <TextField
                                id="standard-name"
                                label="Enter Something"
                                className={classes.textField}
                                value={this.state.text}
                                onChange={this.onChange}
                                margin="normal"
                              />
                              {this.state.emojiToggle ? (
                                    <div>
                                        <EmojiPicker onEmojiClick={this.handleClick}/>
                                        <Button
                                            className={classes.cancel}
                                            onClick={this.handleButton}
                                            color="danger"
                                            variant="outlined">
                                            Close
                                        </Button>
                                    </div>
                                )
                                : (
                                    <div>
                                        <Button onClick={this.handleButton} color="primary" variant="outlined">
                                            Show Emojis
                                        </Button>

                                        <Button onClick={this.onSubmit} style={{ marginLeft: '10px'}} color="primary" variant="outlined">
                                            Submit
                                        </Button>


                                    </div>
                                )}
                              {/* End  Form */}
                            </form>
                        </Paper>
                    </Grid>
                </Grid>
                <Footer/>
            </div>
        );
    }
}
export default withStyles(styles)(App);

最佳答案

Console.log() 在状态完成更新之前执行。 因为setState()是一个异步函数

this.setState({
  text: this.state.text,
  items: [this.state.text]
}, () => console.log(this.state.items));

关于reactjs - 单击两次时 React 会更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55348078/

相关文章:

javascript - React-spring:包含动画图像的动画 div

javascript - Material-UI菜单高度问题

javascript - 从 React.js 组件到 Node.js 服务器的 POST 请求出现问题

css - 样式化组件/ react /语义/ Prop 和计算

reactjs - 使用输入更新 redux 状态

javascript - React.addons.batchedUpdates API 的用途是什么?

javascript - 在 redux 操作中查询 api 时出现无限循环

javascript - react 切换列表竞争条件?

javascript - React Component 给我不可预测的结果

reactjs - 如何使用 Formik 和 Redux-Saga 处理表单状态