Joe*_*dee 157 javascript reactjs
我有以下React组件:
export default class MyComponent extends React.Component {
onSubmit(e) {
e.preventDefault();
var title = this.title;
console.log(title);
}
render(){
return (
...
<form className="form-horizontal">
...
<input type="text" className="form-control" ref={(c) => this.title = c} name="title" />
...
</form>
...
<button type="button" onClick={this.onSubmit} className="btn">Save</button>
...
);
}
};
Run Code Online (Sandbox Code Playgroud)
控制台正在给我undefined
- 任何想法这个代码有什么问题?
Mik*_*ans 244
这里有三个答案,取决于您(被迫)工作的React的版本,以及是否要使用钩子.
根据React文档和教程,通过正确操作.您正在编写一个基于两件事呈现的UI:
你没做的是生成一个输入元素DOM节点,然后键入它.您正在生成必须显示可操作文本字符串的UI,并且操作会更改Component的状态,这可能会导致重新呈现.国家永远是最终的权威,而不是DOM.DOM是一个事后的想法,它只是您碰巧使用的特定UI框架.
因此,为了正确地执行操作,组件具有状态值,通过输入字段显示,我们可以通过使UI元素将更改事件发送回组件来更新它:
var Component = React.createClass({
getInitialState: function() {
return {
inputValue: ''
};
},
render: function() {
return (
//...
<input value={this.state.inputValue} onChange={this.updateInputValue}/>
//...
);
},
updateInputValue: function(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Run Code Online (Sandbox Code Playgroud)
你键入输入元素,你的输入元素没有任何反应,事件被立即截获并终止,React触发<input>
事件的函数.这个功能要求反应更新组件的状态,使其具有正确的值,然后再与可再重新描绘与新的更新你的UI,所以只有那么做用户界面显示您键入一个字母.所有这些都在几毫秒内发生,所以看起来你正常输入的东西,但这绝对不是发生的事情.
基于评论的附录
UI输入表示状态值(考虑如果用户在中途关闭其选项卡会发生什么,并且选项卡已恢复.是否应该还原所有填充的值?如果是,那就是状态).这可能会让你觉得大型表单需要几十甚至一百个输入表单,但React是以可维护的方式建模你的UI:你没有100个独立的输入字段,你有相关的输入组,所以你捕获每个组件中的组,然后将"主"表单构建为组的集合.
MyForm:
render:
<PersonalData/>
<AppPreferences/>
<ThirdParty/>
...
Run Code Online (Sandbox Code Playgroud)
这比一个巨大的单一形式组件更容易维护.将组拆分为具有状态维护的组件,其中每个组件仅负责一次跟踪一些输入字段.
您可能也觉得写出所有代码是"麻烦",但这是一种虚假的拯救:开发者 - 不是你,包括未来的你,实际上从看到所有这些输入明确地连接中获益很大,因为它使代码路径更容易跟踪.但是,您始终可以进行优化.例如,您可以编写状态链接器
MyComponent = React.createClass({
getInitialState() {
return {
firstName: this.props.firstName || "",
lastName: this.props.lastName || ""
...: ...
...
}
},
componentWillMount() {
Object.keys(this.state).forEach(n => {
let fn = n + 'Changed';
this[fn] = evt => {
let update = {};
update[n] = evt.target.value;
this.setState(update);
});
});
},
render: function() {
return Object.keys(this.state).map(n => {
<input
key={n}
type="text"
value={this.state[n]}
onChange={this[n + 'Changed']}/>
});
}
});
Run Code Online (Sandbox Code Playgroud)
当然,还有改进的版本,所以点击https://npmjs.com并搜索你最喜欢的React状态链接解决方案.开源主要是关于找到其他人已经完成的事情,并使用它而不是自己从头开始编写所有内容.
从React 16开始(以15.5开始软启动),render
不再支持该调用,并且需要使用类语法.这改变了两件事:明显的类语法,还有可以"免费"执行的updateInputValue
上下文绑定setState
,因此为了确保事情仍然有效,请确保render
在this.state.inputValue
处理程序中使用"胖箭头"表示法来保留匿名函数,例如在createClass
我们这里的代码中使用:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
};
}
render() {
return (
//...
<input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
//...
);
},
updateInputValue(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Run Code Online (Sandbox Code Playgroud)
您可能还看到人们this
在构造函数中使用它们的所有事件处理函数,如下所示:
constructor(props) {
super(props);
this.handler = this.handler.bind(this);
...
}
render() {
return (
...
<element onclick={this.handler}/>
...
);
}
Run Code Online (Sandbox Code Playgroud)
不要那样做.
几乎在你使用的任何时候createClass
,众所周知的"你做错了"都适用.您的类已经定义了原型,使用普通事件转发而不是在构造函数中复制所有函数调用.现在,您已经增加了bug表面,并且更难以跟踪错误,因为问题可能出在构造函数中而不是您调用代码的位置.除了对您(拥有或选择)使用的其他人施加维护负担之外.
是的,我知道反应文档说没关系.不是,不要这样做.
从React 16.8开始,函数组件(即字面上只是一个函数,this
可以使用某些作为参数的函数,就好像它是一个组件类的实例,而不用编写一个类)也可以通过使用钩子来给定状态.
如果您不需要完整的类代码,并且单个实例函数可以执行,那么您现在可以使用onWhatever
钩子来获取单个状态变量及其更新函数,其工作方式与上面的示例大致相同,除非没有该onChange
函数调用:
import { useState } from 'react';
function myFunctionalComponentFunction() {
const [input, setInput] = useState(''); // '' is the initial state value
return (
<div>
<label>Please specify:</label>
<input value={input} onInput={e => setInput(e.target.value)}/>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
以前,类和函数组件之间的非官方参数是"函数组件没有状态",因此我们不能再隐藏在那个函数组件之后:函数组件和类组件之间的区别可以在很好的页面中找到- 写入反应文档(没有快捷方便的单行解释,以方便你误解!),你应该阅读这些内容,以便你知道自己在做什么,从而知道你是否选择了最好的(对你而言意味着什么)解决方案来自己编程出于你遇到的问题.
小智 21
你应该在类 MyComponent extends React.Component 下使用构造函数
constructor(props){
super(props);
this.onSubmit = this.onSubmit.bind(this);
}
Run Code Online (Sandbox Code Playgroud)
然后你会得到标题的结果
小智 15
返回一个有状态的值以及一个更新它的函数。在初始渲染期间,返回的状态(state)
与作为第一个参数传递的值相同(initialState)
。该setState
函数用于更新状态。它接受新的状态值并将组件的重新渲染排入队列。
src ---> https://reactjs.org/docs/hooks-reference.html#usestate
useRef
返回一个可变的 ref 对象,其.current
属性被初始化为传递的参数(initialValue)
。返回的对象将在组件的整个生命周期内持续存在。
src ---> https://reactjs.org/docs/hooks-reference.html#useref
import { useRef, useState } from "react";
export default function App() {
const [val, setVal] = useState('');
const inputRef = useRef();
const submitHandler = (e) => {
e.preventDefault();
setVal(inputRef.current.value);
}
return (
<div className="App">
<form onSubmit={submitHandler}>
<input ref={inputRef} />
<button type="submit">Submit</button>
</form>
<p>Submit Value: <b>{val}</b></p>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
小智 14
通过执行以下操作来管理以获取输入字段值:
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.state = {
username : ''
}
this.updateInput = this.updateInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
updateInput(event){
this.setState({username : event.target.value})
}
handleSubmit(){
console.log('Your input value is: ' + this.state.username)
//Send state to the server code
}
render(){
return (
<div>
<input type="text" onChange={this.updateInput}></input>
<input type="submit" onClick={this.handleSubmit} ></input>
</div>
);
}
}
//output
//Your input value is: x
Run Code Online (Sandbox Code Playgroud)
Bre*_*rne 12
给<input>
一个唯一的id
<input id='title' ...>
Run Code Online (Sandbox Code Playgroud)
然后使用标准的 Web API在 DOM 中引用它
const title = document.getElementById('title').value
Run Code Online (Sandbox Code Playgroud)
无需在每次按键时不断更新 React 状态。只需在需要时获取值。
在反应16中,我使用
<Input id="number"
type="time"
onChange={(evt) => { console.log(evt.target.value); }} />
Run Code Online (Sandbox Code Playgroud)
小智 7
在功能组件中:-
export default function App(){
const [state, setState] = useState({
value:'',
show:''
});
const handleChange = (e) => {
setState({value: e.target.value})
}
const submit = () => {
setState({show: state.value})
}
return(
<>
<form onSubmit={()=>submit()}>
<input type="text" value={state.value} onChange={(e)=>handleChange(e)} />
<input type="submit" />
</form>
<h2>{state.show}</h2>
</>
)}
Run Code Online (Sandbox Code Playgroud)
小智 6
我通过绑定到函数成功地做到了这this
一点
updateInputValue(evt)
this.updateInputValue = this.updateInputValue.bind(this);
然而输入value={this.state.inputValue}
......结果证明不是一个好主意。
这是 babel ES6 中的完整代码:
class InputField extends React.Component{
constructor(props){
super(props);
//this.state={inputfield: "no value"};
this.handleClick = this.handleClick.bind(this);
this.updateInputValue = this.updateInputValue.bind(this);
}
handleClick(){
console.log("trying to add picture url");
console.log("value of input field : "+this.state.inputfield);
}
updateInputValue(evt){
//console.log("input field updated with "+evt.target.value);
this.state={inputfield: evt.target.value};
}
render(){
var r;
r=<div><input type="text" id="addpixinputfield"
onChange={this.updateInputValue} />
<input type="button" value="add" id="addpix" onClick={this.handleClick}/>
</div>;
return r;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
export default class App extends React.Component{
state={
value:'',
show:''
}
handleChange=(e)=>{
this.setState({value:e.target.value})
}
submit=()=>{
this.setState({show:this.state.value})
}
render(){
return(
<>
<form onSubmit={this.submit}>
<input type="text" value={this.state.value} onChange={this.handleChange} />
<input type="submit" />
</form>
<h2>{this.state.show}</h2>
</>
)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
278580 次 |
最近记录: |