我从React.js开始,我想做一个简单的表单,但在文档中我发现了两种方法。
first one正在使用参考:
var CommentForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var author = React.findDOMNode(this.refs.author).value.trim();
var text = React.findDOMNode(this.refs.text).value.trim();
if (!text || !author) {
return;
}
// TODO: send request to the server
React.findDOMNode(this.refs.author).value = '';
React.findDOMNode(this.refs.text).value = '';
return;
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something..." ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
second one在React组件中使用状态:
var TodoTextInput = React.createClass({
getInitialState: function() {
return {
value: this.props.value || ''
};
},
render: function() /*object*/ {
return (
<input className={this.props.className}
id={this.props.id}
placeholder={this.props.placeholder}
onBlur={this._save}
value={this.state.value}
/>
);
},
_save: function() {
this.props.onSave(this.state.value);
this.setState({value: ''
});
});
如果有的话,我看不出两种选择的利弊。 感谢。
答案 0 :(得分:132)
简短版本:避免参考。
它们对可维护性不利,并且失去了WYSIWYG模型渲染提供的许多简单性。
你有一张表格。您需要添加一个重置表单的按钮。
输入中有CCV编号字段,应用程序中的某些其他字段是数字。现在您需要强制用户只输入数字。
我们需要将控制权交还给父母。数据现在是道具,我们需要对变化做出反应。
sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js
人们认为裁判更容易&#39;而不是保持状态。这可能在前20分钟都是如此,在我之后的经历中并非如此。把自己放在一个位置说'#34;是的,我会在5分钟内完成它&#34;而不是&#34;当然,我只是重写一些组件&#34;。
答案 1 :(得分:97)
我已经看到一些人引用上述答案作为一个理由,从来没有使用过refs&#34;我想给我(以及其他一些我已经说过的React开发者)意见。
不要使用refs&#34;在谈论将它们用于组件实例时,情绪是正确的。这意味着,您不应该使用refs来获取组件实例并在其上调用方法。这是使用refs的错误方法,当refs快速向南移动时。
使用refs的正确(并且非常有用)方法是当您使用它们从DOM获取某些值时。例如,如果你有一个输入字段将ref附加到该输入,那么稍后通过ref获取值就可以了。如果没有这种方式,您需要经过一个相当精心设计的过程,以使您的输入字段与您的本地状态或助焊剂存储保持同步 - 这似乎是不必要的。
2019年编辑:你好朋友的未来。除了我几年前提到的^,使用React Hooks,refs也是一种很好的方式来跟踪渲染之间的数据,并且不仅限于抓取DOM节点。答案 2 :(得分:5)
TL; DR 一般来说,refs
违反了React的declarative philosophy,因此您应该将它们作为最后的手段。尽可能使用state / props
。
要了解您使用refs
与state / props
的位置,让我们看一下React遵循的一些设计原则。
Per React documentation关于refs
避免将refs用于以声明方式完成的任何事情。
Per React关于Escape Hatches
的设计原则如果某些对构建应用程序有用的模式难以以声明方式表达,我们将为其提供必要的API。 (他们在这里链接到refs)
这意味着React的团队建议避免使用refs
并使用state / props
来执行任何可以以被动/声明方式完成的事情。
使用refs的正确(非常有用)方法是当你使用它们从DOM中获取某些值时...
虽然你可以这样做,但你会反对React的哲学。如果您在输入中有价值,那么肯定来自state / props
。为了保持代码的一致性和可预测性,您应该坚持使用state / props
。我承认refs
有时会为您提供更快的解决方案,因此如果您进行概念验证,快速且脏的是可以接受的。
这为refs
管理焦点,文本选择或媒体播放。 触发势在必行的动画。 与第三方DOM库集成。
答案 3 :(得分:0)
此帖子很旧。
在这件事上,我将分享我的一点经验。
我正在研究一个大型组件(414行),其中包含许多“动态”输入和涉及的许多缓存数据。 (我不是在页面上一个人工作,我的感觉告诉我,代码的结构可能可以更好地拆分,但这不是重点(嗯,可能是但我正在处理)
我首先使用state处理输入值:
const [inputsValues, setInputsValues] = useState([])
const setInputValue = (id, value) => {
const arr = [...inputsValues]
arr[id] = value
setInputsValues(arr)
}
当然还有输入:
value={inputsValues[id] || ''}
onChange={event => setInputValue(id, event.target.value)}
渲染是如此之重,以至于输入的变化令人讨厌(****(不要试图按住键,文本只会在暂停后出现)
我确定我可以使用裁判避免这种情况。
像这样结束:
const inputsRef = useRef([])
和输入内容:
ref={input => (inputsRef.current[id] = input)}
[ 就我而言,输入是Material-UI TextField,所以它是:
inputRef={input => (inputsRef.current[id] = input)}
]
感谢这一点,没有重新渲染,输入很流畅,功能相同。它将节省周期和计算,因此也节省了能源。为地球x)
我的结论:甚至可能需要useRef作为输入值。