gpt4 book ai didi

javascript - 将 handleSubmit() 传递给子组件不会修改父组件的状态

转载 作者:行者123 更新时间:2023-11-30 06:14:30 25 4
gpt4 key购买 nike

我是 React 和 Javascript 的新手。

我正在尝试让用户填写一个描述“Mob”应该是什么样子的表格。当用户点击提交时,我希望 handleSubmit()(通过父级传入)修改父级的状态,这是一个对象。然而,这种行为并没有发生。

这是父组件,称为 App。

class App extends React.Component {
constructor(props) {
super(props);

this.state = {
mob: new Mob("", "")
};

this.handleSubmit = this.handleSubmit.bind(this);
}

handleSubmit(event) {
event.preventDefault();
alert("A name was submitted: " + this.state.vnum + " event value: " + event.state.vnum);
const newMob = new Mob(event.state.vnum, event.state.shortDesc);

this.setState({
mob: newMob
});
}

render() {
return (
<div>
<MobForm mob={this.state.mob} onSubmit={() => this.handleSubmit} />
{console.log("parsed mob vnum: " + this.state.mob.vnum)}
</div>
);
}
}

子组件,称为 MobForm

class MobForm extends React.Component {
render() {
return (
<div>
<form onSubmit={this.props.onSubmit}>
<CreateStringInputField
name="vnum"
label="vnum:"
/>
<CreateStringInputField
name="shortDesc"
label="Short Desc:"
/>
<input type="submit" value="Submit" />
</form>
{console.log(this.state)}
</div>
);
}
}

正在调用 CreateStringInputField()

function CreateStringInputField(props) {
return (
<div name="row">
<label>
<b>{props.label}</b>
<br />
<input
type="text"
name={props.name}
label={props.label}
/>
</label>
</div>
);
}

如果重要的话,这就是“Mob”的样子。

class Mob {
constructor(vnum, shortDesc) {
this.vnum = vnum;
this.shortDesc = shortDesc;
};
}

我希望看到 {console.log("parsed mob vnum: "+ this.state.mob.vnum)} 打印出用户输入的 vnum。相反,我什么也没看到。我怎样才能达到这个预期的输出?

最佳答案

使用 React,您无需使用普通类。相反,类 extends 提供的 React 组件(ComponentPureComponent) 如果您不需要 state,然后将使用仅返回一些 JSX 的普通函数。

工作示例:https://codesandbox.io/s/simple-form-kdh3w


index.js

import React from "react";
import { render } from "react-dom";
import MobForm from "./components/MobForm";

// simple function that returns "MobForm" and it gets rendered by ReactDOM
function App() {
return <MobForm />;
}

// applies "App" to a <div id="root"></div> in the public/index.html file
render(<App />, document.getElementById("root"));

components/MobForm/index.js(有状态父组件)

import React, { Component } from "react";
import Form from "../Form";

const initialState = {
vnum: "",
shortDesc: ""
};

// a stateful parent that manages child state
class MobForm extends Component {
constructor(props) {
super(props);
this.state = initialState;

// since the class fields are normal functions, they'll lose context
// of "this" when called as a callback. therefore, they'll need
// to be bound to "this" -- via bind, "this" is now referring to
// the Class, instead of the global window's "this")
this.handleChange = this.handleChange.bind(this);
this.handleReset = this.handleReset.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

// a reusable class field that stores an input's value via its "name"
// for example: [vnum]: "12345", [shortDesc]: "A number"
// using object destructuring for shorter syntax:
// [event.target.name]: event.target.value
handleChange({ target: { name, value } }) {
this.setState({ [name]: value });
}

// a class field to reset state
handleReset() {
this.setState(initialState);
}

// a class field to "submit" the form and alert what's currently in state
handleSubmit(event) {
// preventDefault prevents page refreshes
event.preventDefault();

// JSON.stringify allows you to print the contents of an object
// otherwise, you'll just see [object Object]
alert(JSON.stringify(this.state, null, 4));

// clears state after submitting form
this.handleReset();
}

render() {
return (
// passing down state via the spread operator, shorthand for
// "vnum={this.state.vum}" and "shortDesc={this.state.shortDesc}",
// as well as, passing down the class fields from above
<Form
{...this.state}
handleChange={this.handleChange}
handleReset={this.handleReset}
handleSubmit={this.handleSubmit}
/>
);
}
}

export default MobForm;

components/Form/index.js(返回某种形式 JSX 的子函数)

import React from "react";
import PropTypes from "prop-types";
import Input from "../Input";

// using object destructuring to pull out the MobForm's passed down
// state and fields. shorthand for using one parameter named "props"
// and using dot notation: "props.handleChange", "props.handleReset", etc
function Form({ handleChange, handleReset, handleSubmit, shortDesc, vnum }) {
return (
<form style={{ width: 200, margin: "0 auto" }} onSubmit={handleSubmit}>
<Input name="vnum" label="vnum:" value={vnum} onChange={handleChange} />
<Input
name="shortDesc"
label="Short Desc:"
value={shortDesc}
onChange={handleChange}
/>
<button type="button" onClick={handleReset}>
Reset
</button>{" "}
<button type="submit">Submit</button>
</form>
);
}

// utilizing "PropTypes" to ensure that passed down props match
// the definitions below
Form.propTypes = {
handleChange: PropTypes.func.isRequired,
handleReset: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
shortDesc: PropTypes.string,
vnum: PropTypes.string
};

export default Form;

components/Input/index.js(可重复使用的输入函数)

import React from "react";
import PropTypes from "prop-types";

// once again, using object destructuring to pull out the Form's
// passed down state and class fields.
function Input({ label, name, value, onChange }) {
return (
<div name="row">
<label>
<b>{label}</b>
<br />
<input
type="text"
name={name}
label={label}
value={value}
onChange={onChange}
/>
</label>
</div>
);
}

// utilizing "PropTypes" to ensure that passed down props match
// the definitions below
Input.propTypes = {
label: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
value: PropTypes.string,
onChange: PropTypes.func.isRequired
};

export default Input;

关于javascript - 将 handleSubmit() 传递给子组件不会修改父组件的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56998932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com