Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
56 views
in Technique[技术] by (71.8m points)

javascript - Why is setState not setting the state of the value 'access' in my code?

It's a basic form taking inputs. When the user goes to 'submit' the form, the checked box values form a string to be used for a csv (not important). Yet when I try to setState access (which should store this string) the value doesn't actually change. I'm new to react so... please help.

I've even put in comments that when the string is formed, I test it by using an alert and the string is correct. However, after setState access, access' value has not changed.

import React from 'react';
import {Link} from 'react-router-dom';

class CreateAnnouncementPage extends React.Component{
    constructor(props) {
        super(props)

        this.state = {
            title: '',
            content: '',
            firstyear: '',
            secondyear: '',
            thirdyear: '',
            fourthyear: '',
            access: '',
            errormsg: ''
        }
    }

    titleInput = (titleInputEvent) => {
        this.setState(
            {title: titleInputEvent.target.value}
        );
    }

    contentInput = (contentInputEvent) => {
        this.setState(
            {content: contentInputEvent.target.value}
        );
    }

    firstYearChecked = () => {
        if (this.state.firstyear === '') {
            this.setState(
                {firstyear: "1"}
            );
        } else {
            this.setState(
                {firstyear: ''}
            );
        }
    }

    secondYearChecked = () => {
        if (this.state.secondyear === '') {
            this.setState(
                {secondyear: "2"}
            );
        } else {
            this.setState(
                {secondyear: ''}
            );
        }
    }

    thirdYearChecked = () => {
        if (this.state.thirdyear === '') {
            this.setState(
                {thirdyear: "3"}
            );
        } else {
            this.setState(
                {thirdyear: ''}
            );
        }
    }

    fourthYearChecked = () => {
        if (this.state.fourthyear === '') {
            this.setState(
                {fourthyear: "4"}
            );
        } else {
            this.setState(
                {fourthyear: ''}
            );
        }
    }

    submitAnnouncement = (submitAnnouncementEvent) => {
        const{firstyear, secondyear, thirdyear, fourthyear, access} = this.state;
        var accessString = "_" + firstyear + secondyear + thirdyear + fourthyear;

        // this gives back the correct string
        alert(accessString);

        // but for some reason this isn't setting access as the string
        this.setState(
            {access: accessString}
        );

        console.log(this.state.access);

        alert(access);

        if (access === '') {
            submitAnnouncementEvent.preventDefault();
            this.setState(
                {errormsg: "Please select who sees the announcement."}
            );
        } else {
            // this needs to save the announcement in a csv which is then loaded 
            // in when a student goes to the announcement page

            // perhaps if the announcement is saved as a csv, the title defines
            // who can access it e.g. if it's year 1 and 2 the title could be 
            // the date then _12 for the year groups.
            alert("Announcement sent.")
        }
    }

    render() {
        const{errormsg, title, content, firstyear, secondyear, thirdyear, fourthyear} = this.state;
        return(
            <div>
                <h1>Create Announcement</h1>
                <p>{errormsg}</p>
                <form onSubmit={this.submitAnnouncement}>
                    <div> 
                        <label>Announcement Title:</label>
                        <input type='text' value={title} required onChange={this.titleInput}/>
                    </div>
                    <div>
                        <label>Announcement Content:</label>
                        <textarea value={content} required onChange={this.contentInput} cols='50'/>
                    </div>
                    <div>
                        <label>Make announcement available for:</label><br/>
                        <label>First Year</label>
                        <input type='checkbox' value={firstyear} onChange={this.firstYearChecked}/><br/>
                        <label>Second Year</label>
                        <input type='checkbox' value={secondyear} onChange={this.secondYearChecked}/><br/>
                        <label>Third Year</label>
                        <input type='checkbox' value={thirdyear} onChange={this.thirdYearChecked}/><br/>
                        <label>Fourth Year</label>
                        <input type='checkbox' value={fourthyear} onChange={this.fourthYearChecked}/><br/>
                    </div>
                    <input type='submit' value="Send Announcement"/>
                </form>
                <Link to="/staff/announcement-editor"><p>Return</p></Link>
            </div>
        );
    }
}

export default CreateAnnouncementPage;
question from:https://stackoverflow.com/questions/65672145/why-is-setstate-not-setting-the-state-of-the-value-access-in-my-code

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Always remember, setting a state is an asynchronous work, This is the very first and important thing you learn in react, React does not guarantee that the state will be updated immediately even after setting a state

So it provides a way, for setState you can pass in the second parameter, ie. the callback which react will trigger when state is updated successfully.

submitAnnouncement = (submitAnnouncementEvent) => {
  const {
    firstyear,
    secondyear,
    thirdyear,
    fourthyear,
    access
  } = this.state;
  var accessString = "_" + firstyear + secondyear + thirdyear + fourthyear;

  // this gives back the correct string
  alert(accessString);

  this.setState({
      access: accessString
    },
    // move your code into the callback
    () => {
      console.log(this.state.access);

      alert(access);

      if (access === '') {
        submitAnnouncementEvent.preventDefault();
        this.setState({
          errormsg: "Please select who sees the announcement."
        });
      } else {
        alert("Announcement sent.")
      }

    }
  );

}

setState Api reference


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...