[英]React - change input defaultValue by passing props
考虑这个例子:
var Field = React.createClass({
render: function () {
// never renders new value...
return (
<div>
<input type="text" defaultValue={this.props.value || ''} />
</div>
);
}
});
var App = React.createClass({
getInitialState: function () {
return {value: 'Hello!'};
},
changeTo: function (str) {
this.setState({value: str});
},
render: function () {
return (
<div>
<Field value={this.state.value} />
<button onClick={this.changeTo.bind(null, 'Whyyyy?')}>Change to "Whyyyy?"</button>
<button onClick={this.changeTo.bind(null, void 0)}>Change to undefined</button>
</div>
);
}
});
React.render(
<App />,
document.getElementById('app')
);
我想将值传递给defaultValue
作为哑输入组件的道具。 但是它永远不会重新渲染它。
正如前面提到的答案, defaultValue
仅在表单的初始加载时设置。 之后,它不会“自然”更新,因为目的只是设置初始默认值。
如果需要将key
传递给包装器组件(例如在Field
或App
组件上),您可以解决此问题,但在更实际的情况下,它可能是form
组件。 一个好的key
应该是传递给表单的资源的唯一值 - 例如存储在数据库中的 id。
在您的简化情况下,您可以在 Field 渲染中执行此操作:
<div key={this.props.value}>
<input type="text" defaultValue={this.props.value || ''} />
</div>
在更复杂的表单案例中,例如,如果您的 onSubmit 操作提交给 API 但停留在同一页面上,则类似这样的事情可能会得到您想要的结果:
const Form = ({item, onSubmit}) => {
return (
<form onSubmit={onSubmit} key={item.id}>
<label>
First Name
<input type="text" name="firstName" defaultValue={item.firstName} />
</label>
<label>
Last Name
<input type="text" name="lastName" defaultValue={item.lastName} />
</label>
<button>Submit!</button>
</form>
)
}
Form.defaultProps = {
item: {}
}
Form.propTypes = {
item: PropTypes.object,
onSubmit: PropTypes.func.isRequired
}
当使用不受控制的表单输入时,我们通常在提交之后才关心这些值,所以这就是为什么只在您真正想要更新 defaultValues 时才强制重新渲染更为理想(提交之后,而不是每次更改时)个人输入)。
如果您还在编辑相同的表单并且担心 API 响应可能会返回不同的值,您可以提供一个组合键,如 id 加时间戳。
defaultValue仅适用于初始加载。 在那之后,它不会得到更新。 您需要为Field组件维护状态:
var Field = React.createClass({
//transfer props to state on load
getInitialState: function () {
return {value: this.props.value};
},
//if the parent component updates the prop, force re-render
componentWillReceiveProps: function(nextProps) {
this.setState({value: nextProps.value});
},
//re-render when input changes
_handleChange: function (e){
this.setState({value: e.target.value});
},
render: function () {
// render based on state
return (
<div>
<input type="text" onChange={this._handleChange}
value={this.state.value || ''} />
</div>
);
}
});
我相当肯定这与Controlled vs. Uncontrolled 输入有关。
如果我理解正确,因为您的<input>
是不受控制的(未定义value
属性),那么该值将始终解析为初始化时使用的值。 在这种情况下Hello!
.
为了克服这个问题,您可以添加一个value
属性并在onChange
期间设置它:
var Field = React.createClass({
render: function () {
// never renders new value...
return (
<div>
<input type="text" defaultValue={this.props.default || ''} value={this.props.value} />
</div>
);
}
});
您可以有条件地进行输入,然后每次要强制更新defaultValue
您只需要卸载输入,然后立即再次渲染它。
问题在这里:
onClick={this.changeTo.bind(null, 'Whyyyy?')}
我很好奇你为什么绑定到 null。
您想绑定到“this”,以便 changeTo 将在 THIS 对象中设置状态。
尝试这个
<button onClick={this.changeTo.bind(this, 'Whyyyy?')}>Change to "Whyyyy?"</button>
<button onClick={this.changeTo.bind(this, void 0)}>Change to undefined</button>
在 Javascript 中,当一个函数被调用时,它在它被调用的范围内被调用,而不是在它被写入的地方(我知道,这似乎违反直觉)。 为了确保在你编写它的上下文中调用它,你需要'.bind(this)'。
要了解有关绑定和函数作用域的更多信息,有很多在线教程(有些比其他教程要好得多)-您可能会喜欢这个: http : //ryanmorr.com/understanding-scope-and-context-in-javascript/
如果您使用的是 firefox 或 chrome,我还建议您使用 React Dev 工具,这样您就可以看到 state.message 没有改变: https ://facebook.github.io/react/blog/2015/09 /02/new-react-developer-tools.html
使用条件渲染,然后组件将加载正确的初始值。 在这个模块中的东西:
class MenuHeaderInput extends React.Component{
constructor(props){
super(props);
this.handleBlur = this.handleBlur.bind (this);
}
handleBlur (e) {
this.props.menuHeaderUpdate(e.target.value);
}
render(){
if (this.props.menuHeader) {
return (
<div className="w3-row w3-margin" onClick = {() => this.props.handleTitleClick (10)}>
<div className="w3-third" ><pre></pre></div>
<input
className = {"w3-third w3-input w3-jumbo " + EDIT_COLOR}
type = "text"
defaultValue = {this.props.menuHeader}
onBlur = {this.handleBlur}
/>
<div className="w3-third" ><pre></pre></div>
</div>
)
}
else {
return null;
}
}
}
与以上 Sia 的出色回答相关: https : //stackoverflow.com/a/41962233/4142459 。
就我而言,我有几种方法可以更新表单:
我发现确保表单状态反映在其输入中的最简单方法确实是:
key
prop(只要它位于 DOM 树中的输入之上。key
,不需要发生更新。key
为一个简单的formHistoricalVersion
并且当用户键入/选择/等与表单字段的值交互时发生某些外部更新时,我增加了 formHistoricalVersion。我尝试过的其他解决方案:
setImmediate
的形式转化到装载微调时,他们首先清除它,然后设置isLoading
回false
的setImmediate。key
:这非常有效,但是每当用户输入时它都会有一个奇怪的光点,所以我不得不摆脱它。field.id
)放置一个静态键(如上面的答案所建议的)并没有涵盖我拥有的所有用例。总之,使用 react/redux 设置表单的键非常容易,我只需添加以下内容:
return {
...state,
formFieldState: payload.formFields,
historicalFormVersion: state.historicalFormVersion + 1
}
这是必要的,因为我使用了一些 3rd 方库和我自己的数字输入,它们将值作为道具但使用值作为默认值:
const NumberDisplay: FunctionComponent = ({ value, setValue }) => (
<input
defaultValue={convertToSpecialNumberDisplay(value)}
onBlur={(e) => convertToSpecialNumberDisplay(e.target.value)}
onFocus={(e) => convertToNumberFromDisplay(e.target.value)}
onChange={(e) => setValue(e.target.value)}
/>
)
整体表格的近似 Redux:
const FullForm: FunctionComponent = () => {
const dispatch = useDispatch();
const formState = useState((state) => state.formState);
const formHistoricalVersion = useState((state) => state.formHistoricalVersion);
return (
<form key={formHistoricalVersion}>
{renderFormFields(formState, dispatch)}
</form>
)
}
我也面临这个问题,我所做的是在道具发生变化时手动更新输入值。 将此添加到您的 Field 反应类:
componentWillReceiveProps(nextProps){
if(nextProps.value != this.props.value) {
document.getElementById(<element_id>).value = nextProps.value
}
}
您只需要向您的元素添加一个 id 属性,以便可以定位它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.