Javascript 将handleSubmit()传递给子组件不会修改父组件';s州
我不熟悉React和Javascript 我试图让一个用户填写一个表格,描述“暴徒”应该是什么样子。当用户点击submit时,我希望Javascript 将handleSubmit()传递给子组件不会修改父组件';s州,javascript,reactjs,Javascript,Reactjs,我不熟悉React和Javascript 我试图让一个用户填写一个表格,描述“暴徒”应该是什么样子。当用户点击submit时,我希望handleSubmit()(通过父对象传入)修改父对象的状态。然而,这种行为并没有发生 这是父组件,称为App class App extends React.Component { constructor(props) { super(props); this.state = { mob: new
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>
);
}
}
如果这很重要,“暴徒”就是这样的
class Mob {
constructor(vnum, shortDesc) {
this.vnum = vnum;
this.shortDesc = shortDesc;
};
}
我希望看到{console.log(“解析的mob vnum:+this.state.mob.vnum)}
打印出用户输入的vnum。相反,我什么也没看到。我如何才能达到预期的输出?在这一行中
<MobForm mob={this.state.mob} onSubmit={() => this.handleSubmit} />
使用React,您不需要使用普通类。相反,类
扩展了提供的React组件(component
或PureComponent
)或,如果您不需要state
,那么将使用只返回一些JSX的普通函数
工作示例:
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"));
从“React”导入React;
从“react dom”导入{render};
从“/components/MobForm”导入MobForm;
//返回“MobForm”并由ReactDOM呈现的简单函数
函数App(){
返回;
}
//将“应用程序”应用于public/index.html文件中的
render(,document.getElementById(“根”));
组件/MobForm/index.js(有状态父组件)
import React,{Component}来自“React”;
从“./表格”导入表格;
常量初始状态={
vnum:“”,
shortDesc:“
};
//管理子状态的有状态父级
类MobForm扩展组件{
建造师(道具){
超级(道具);
this.state=初始状态;
//由于类字段是普通函数,它们将丢失上下文
//当作为回调调用时,调用“this”。因此,它们需要
//要绑定到“this”--通过绑定,“this”现在指的是
//类,而不是全局窗口的“this”)
this.handleChange=this.handleChange.bind(this);
this.handleReset=this.handleReset.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
//一个可重用的类字段,通过其“名称”存储输入值
//例如:[vnum]:“12345”,[shortDesc]:“一个数字”
//对较短的语法使用对象分解:
//[event.target.name]:event.target.value
handleChange({target:{name,value}}){
this.setState({[name]:value});
}
//要重置状态的类字段
handleReset(){
此.setState(初始状态);
}
//“提交”表单并提醒当前状态的类字段
handleSubmit(事件){
//preventDefault防止页面刷新
event.preventDefault();
//stringify允许您打印对象的内容
//否则,您将只看到[object]
警报(JSON.stringify(this.state,null,4));
//提交表单后清除状态
这个.handleReset();
}
render(){
返回(
//通过spread运算符传递状态,简写为
//“vnum={this.state.vum}”和“shortDesc={this.state.shortDesc}”,
//以及从上面传递类字段
);
}
}
导出默认表单;
组件/Form/index.js(返回一些表单JSX的子函数)
从“React”导入React;
从“道具类型”导入道具类型;
从“./Input”导入输入;
//使用对象分解来提取移动表单的
//州和地区。使用一个名为“props”的参数的缩写
//并使用点符号:“props.handleChange”、“props.handleReset”等
函数形式({handleChange,handleReset,handleSubmit,shortDesc,vnum}){
返回(
重置
{" "}
提交
);
}
//利用“道具类型”确保传下来的道具匹配
//定义如下
Form.propTypes={
handleChange:PropTypes.func.isRequired,
HandlerReset:PropTypes.func.isRequired,
handleSubmit:PropTypes.func.isRequired,
shortDesc:PropTypes.string,
vnum:PropTypes.string
};
导出默认表单;
组件/Input/index.js(一个可重用的输入函数)
从“React”导入React;
从“道具类型”导入道具类型;
//再次,使用对象分解来提取窗体的
//传递的状态和类字段。
函数输入({label,name,value,onChange}){
返回(
{label}
);
}
//利用“道具类型”确保传下来的道具匹配
//定义如下
Input.propTypes={
标签:PropTypes.string.isRequired,
名称:PropTypes.string.isRequired,
值:PropTypes.string,
onChange:PropTypes.func.isRequired
};
导出默认输入;
我能够通过向MobForm传递一个函数来获得我想要的行为,该函数更新了this.state.mob
应用程序
class App extends React.Component {
state = {
mob: new Mob("", "")
};
updateMob = newMob => {
this.setState({
mob: newMob
});
};
render() {
return (
<div>
<MobForm mob={this.state.mob} onSubmit={this.updateMob} />
</div>
);
}
}
在App.handleSubmit()中的警报行生成错误(“已提交名称:“+this.state.vnum+”事件值:“+event.statement.vnum”)代码>--错误是无法读取未定义的属性“vnum”
请查看事件的值。它似乎没有名为语句的属性。您还没有在state
上定义vnum
。您是对的,事件没有语句。然而,它似乎也不包含任何值。我已经尝试了event.vnum、event.name等。如何在handleSubmit()中正确提取这些值?请尝试console.log(event)
查看onSubmit
返回的内容我怀疑您尝试执行的操作将需要更多的工作。react文档很好地解释了如何实现您的目标,但我认为这超出了您最初问题的范围。这是一个非常有用的答案。最终,我的决定是成功的
<form onSubmit={this.props.onSubmit}>
<MobForm mob={this.state.mob} onSubmit={this.handleSubmit} />
class MobForm extends React.Component {
constructor(props) {
super(props);
this.state = {
vnum: '',
shortDesc: '',
};
this.handleChangeVnum = this.handleChangeVnum.bind(this);
this.handleChangeShortDesc = this.handleChangeShortDesc.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeVnum(event) {
this.setState({vnum: event.target.value});
}
handleChangeShortDesc(event) {
this.setState({shortDesc: event.target.value});
}
handleSubmit(event) {
this.props.onSubmit(this.state);
event.preventDefault();
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<CreateStringInputField
name="vnum"
label="vnum:"
value={this.state.vnum}
onChange={this.handleChangeVnum}
/>
<CreateStringInputField
name="shortDesc"
label="Short Desc:"
value={this.state.shortDesc}
onChange={this.handleChangeShortDesc}
/>
<input type="submit" value="Submit" />
</form>
{console.log(this.state)}
</div>
);
}
}
function CreateStringInputField(props) {
return (
<div name="row">
<label>
<b>{props.label}</b>
<br />
<input
type="text"
name={props.name}
label={props.label}
value={props.value}
onChange={props.onChange}
/>
</label>
</div>
);
}
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"));
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;
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;
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;
class App extends React.Component {
state = {
mob: new Mob("", "")
};
updateMob = newMob => {
this.setState({
mob: newMob
});
};
render() {
return (
<div>
<MobForm mob={this.state.mob} onSubmit={this.updateMob} />
</div>
);
}
}
state = { vnum: "", shortDesc: "" };
handleSubmit = event => {
event.preventDefault();
const mob = new Mob(this.state.vnum, this.state.shortDesc);
this.props.onSubmit(mob);
};
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<CreateStringInputField
name="vnum"
value={this.state.vnum}
onChange={event => this.setState({ vnum: event.target.value })}
/>
<CreateStringInputField
name="short desc"
value={this.state.shortDesc}
onChange={event => this.setState({ shortDesc: event.target.value })}
/>
<input type="submit" value="Submit" />
</form>
</div>
);
}
}