gpt4 book ai didi

javascript - 提交后的表单未定义 "this"但 react 中的按钮未定义

转载 作者:行者123 更新时间:2023-12-01 15:23:15 24 4
gpt4 key购买 nike

注意:这个问题不是询问如何绑定(bind)事件处理程序。它在问为什么,没有绑定(bind)thisButtononClick 中不一致(它指的是一个对象)和 FormonSubmit(它是 undefined)。

完整问题:

如果我不在构造函数中绑定(bind)方法,我试图检查方法中的 this 对象会发生什么情况。我发现 Form 和 Button 的结果不同。下面是我的代码,以便更好地理解:

const {Button, Form, Input} = Reactstrap;

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

handleClick(){
console.log(this); //This gives complete information about the Button object and its properties
}

handleSubmit(e){
console.log(this); //This one is undefined
e.preventDefault();
}

render(){
return(
<React.Fragment>
<Form onSubmit={this.handleSubmit} >

<Input type="submit" name="submit">Submit</Input>

</Form>

<Button name="butt1" onClick={this.handleClick}>Click</Button>
</React.Fragment>
);
}
}

ReactDOM.render(<Test />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reactstrap/8.4.1/reactstrap.min.js"></script>

我已检查我的问题与 this 不同一个是因为,在提供的问题中,提问者想为组件绑定(bind) this 而在我的问题中,我希望 this 引用 Form,就像它引用按钮。

我试图找到这种不同行为的原因,但我没能成功。你们能否给出相同的原因并提出一种方法,以便 handleSubmit 中的 this 开始引用 Form 对象?

编辑这是我认为的原因,请确认是否正确

由于提交处理程序是用表单定义的,而不是提交按钮,这就是为什么 this 未定义的原因,因为提交被点击,而不是表单。我想我需要一些冒泡捕获之类的东西。

最佳答案

这似乎是 Reactstrap 中的错误(或至少是不一致) .对于普通的 formbutton 元素,React 始终调用没有特定 this 值的处理程序¹(所以在这个例子中,因为 class 代码始终处于严格模式,我们在调用中看到 this 设置为 undefined):

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

handleClick() {
console.log(typeof this);
}

handleSubmit(e) {
console.log(typeof this);
e.preventDefault();
}

render(){
return(
<React.Fragment>
<form onSubmit={this.handleSubmit} >

<input type="submit" name="submit" value="Submit" />

</form>

<button type="button" name="butt1" onClick={this.handleClick}>Click</button>
</React.Fragment>
);
}
}

ReactDOM.render(<Test />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>


But I have read that this inside normal functions is resolved dynamically i.e. who called it.

这是不正确的。对于普通函数和方法,调用中 this 的值由调用者确定。所以我上面说的是 React 做一件事而 Reactstrap 做另一件事。

您可能会想到 DOM 以及它如何处理事件处理程序,这与 React 和(显然)Reactstrap 不同。 DOM 调用您的处理程序并将 this 设置为处理程序附加到的元素。因此,如果您将处理程序附加到 button 并且处理程序是普通函数或方法,则 this 将在处理程序时引用 button由 DOM 调用。这只是 DOM 所做的事情。 react 没有。 Reactstrap 显然取决于它是什么处理程序或它是什么类型的元素(这可能是一个错误)。

this question's answers 中关于 this 的更多信息在this old post on my anemic little blog .


在您的评论中:

One more thing that I want to ask is how to use your code without strict mode, because it doesn't specify strict mode to be used

该示例中的代码处于严格模式的原因有两个:

  1. 正如我之前在回答中提到的,它位于 class 结构中。 class 中的代码总是严格的。 (JavaScript 模块中的代码也是如此。)
  2. 它使用 Babel 来转换 JSX,默认情况下 Babel 在它输出的代码中开启严格模式。

因此,要查看松散模式下会发生什么,您必须不使用 class(足够简单)并且不使用 Babel,或者至少告诉 Babel 不要打开严格模式。我不知道是否有办法告诉 Babel 不要在 Stack Snippets 中使用严格模式(当你在现实世界中使用它时有一种方法),但幸运的是,你没有 将 JSX 与 React 一起使用,这很方便。你可以直接使用React.createElement:

const {createElement} = React;

function Test() {
function handleClick() {
console.log(this === window);
}

function handleSubmit(e) {
console.log(this === window);
e.preventDefault();
}

return createElement(React.Fragment, {
children: [
createElement("form", {
onSubmit: handleSubmit,
children: [
createElement("input", {
type: "submit",
name: "submit",
value: "Submit"
})
]
}),
createElement("button", {
type: "button",
name: "butt1",
onClick: handleClick,
children: ["Click"]
})
]
});
}

ReactDOM.render(createElement(Test), document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>

请注意,回调中的 this 现在是全局 this,因为当您调用没有特定 this 值的普通函数或方法时在松散模式下,回调中的 this 是全局 this(在浏览器上为 window)。


¹ React 的 event documentation 甚至涵盖了这一点,尽管它实际上说的是 this 将是 undefined。只有在严格模式下才是正确的。从技术上讲,在不使用严格模式的情况下使用 React 是可能的——但不是一个好主意。

关于javascript - 提交后的表单未定义 "this"但 react 中的按钮未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62359164/

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