简体   繁体   中英

Accessing state in parent class from a child class

I appreciate the previous assistance from this list. Here is what I want to do. A set of cascading classes that communicate with a server using get or post and receiving a response in JSON. I have done this successfully in the past using HTML5, javascript and JQuery. I would like new code to use React. I've read a number of the articles documenting components, props and classes. I don't quite get it yet. I believe what I attempted is close but still wrong. Babel gives me a syntax error. See the failed code:

class NameForm extends React.Component {
                      constructor(props) {
                        super(props);
                        this.state = {
                          value: ''
                        };
                        this.handleChange = this.handleChange.bind(this);
                        this.handleSubmit = this.handleSubmit.bind(this);
                      }

                      handleChange(event) {
                        const regexpr = /^[0-9\b]+$/;
                        if(event.target.value === '' || regexpr.test(event.target.value)){
                            this.setState({
                            value: event.target.value
                            });
                        }
                      }

                      handleSubmit(event) {
                        alert('A name was submitted: ' + this.state.value);
                        const {theName} = this.state.value;
                        return <NameProcess {"theName"}/>;  /* FAIL ! */
                      }

                      render() {
                        return /*#__PURE__*/React.createElement("form", {
                          onSubmit: this.handleSubmit
                        }, /*#__PURE__*/React.createElement("label", null, "Name:", 
/*#__PURE__*/React.createElement("input", {
                          type: "text",
                          value: this.state.value,
                          onChange: this.handleChange
                        })), /*#__PURE__*/React.createElement("input", {
                          type: "submit",
                          value: "Submit"
                        }));
                  }
                }

NameProcess would be the name of the child class. What am I doing wrong as a beginner?

You have to pass in the value to a specific prop that the child component, NameProcess , will look for. For example, return <NameProcess value={theName} />; and then access it in the child component through this.props.value . However, const {theName} = this.state.value will return undefined unless value is an object that has a property theName . You probably want to do const { value } = this.state instead.

But also, I'm not sure why you're returning this component from the handleSubmit function. What you could do instead, if you're trying to wait for submit until showing the component, is add this to your state to mark when a form is submitted:

this.state = { value: '', submitted: false };

and to your handleSubmit function to update the value to true :

handleSubmit(event) {
    event.preventDefault(); // to prevent default action taken on form submit
    alert('A name was submitted: ' + this.state.value);
    this.setState({ submitted: true });
}

and to your render function to show the child component once submitted:

{this.state.submitted && return <NameProcess value={this.state.theName} />}

As @Yossi mentioned, you may want to clean up your render function using JSX, making your whole file, putting all of these suggestions together, something like this:

class NameForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            submitted: false
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        const regexpr = /^[0-9\b]+$/;
        if(event.target.value === '' || regexpr.test(event.target.value)){
            this.setState({
                value: event.target.value
            });
        }
    }

    handleSubmit(event) {
        event.preventDefault();
        const { value } = this.state;
        alert('A name was submitted: ' + value);
        this.setState({ submitted: true });
    }

    render() {
        const { value, submitted } = this.state;
        return (
            {submitted ? <NameProcess value={value} /> : (
                <form onSubmit={this.handleSubmit}>
                    <label>Name:</label>
                    <input type="text" value={value} onChange={this.handleChange} />
                    <input type="submit" value="Submit" />
                </form>
            )}
        );
    }
}

This worked.

class NameForm extends React.Component {  /*1*/
                      constructor(props) { /*2*/
                        super(props);
                        this.state = { /*3*/
                          value: '',
                          submitted: false
                        }; /*3*/
                        this.handleChange = this.handleChange.bind(this);
                        this.handleSubmit = this.handleSubmit.bind(this);
                      } /*2*/

                      handleChange(event) { /*2 */
                        const regexpr = /^[0-9\b]+$/;

                        if (event.target.value === '' || 
regexpr.test(event.target.value)) { /* 3 */
                          this.setState({ /* 4 */
                            value: event.target.value
                          }); /* 4 */
                        } /* 3 */
                      } /* 2 */

                      handleSubmit(event) { /* 2 */
                        event.preventDefault();
                        const { /* 3 */
                          value
                        } = this.state; /* 3 */
                        alert('A name was submitted: ' + value);
                        this.setState({ /* 3 */
                          submitted: true
                        }); /* 3 */
                      } /* 2 */

                      render() { /* 2 */
                                return this.state.submitted ? 
/*#__PURE__*/React.createElement(NameProcess, { /* 3 */
                                  value: this.state.value
                                }) : 
                                     /*#__PURE__*/React.createElement("form", { /* 3 */ /* 3 */ 
                                       onSubmit: this.handleSubmit
                                }, 
                                /*#__PURE__*/React.createElement("label", null, "Name:"), /*#__PURE__*/React.createElement("input", { /* 3 */ /* 3 */ 
                                  type: "text",
                                  value: this.state.value,
                                  onChange: this.handleChange
                                }), 
                                /*#__PURE__*/React.createElement("input", { /* 3 */ /* 3 */ 
                                  type: "submit",
                                  value: "Submit"
                                })); /* 3 */ 

                              } /* 2 */
                      } /* 1 */

                      class NameProcess extends React.Component {  /*1*/
                          constructor(props) { /*2*/
                            super(props);
                          } /*2*/
                          render(){ /* 2 */
                                  return 'blah!';
                              }  /* 2 */
                      } /* 1 */

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM