用一个例子解释我想要完成的事情是最简单的:
addContact = ev => {
ev.preventDefault();
this.props.setField('contacts', contacts => update(contacts, {$push: [{name: 'NEW_CONTACT'}]}));
this.props.setFocus(`contacts.${this.props.data.contacts.length-1}.name`);
};
在此示例中,this.props.setField
会调度一个操作,该操作会将额外字段添加到我的表单中。
this.props.setFocus
然后尝试关注这个新领域。
这不起作用,因为在调用setFocus
时表单尚未重新呈现。
在dispatch
通话后重新呈现我的组件时,有没有办法获得回调?
如果您需要查看,setField
看起来像这样:
setField(name, value) {
if(_.isFunction(value)) {
let prevValue = _.get(data, name);
if(prevValue === undefined) {
let field = form.fields.get(name);
if(field) {
prevValue = field.props.defaultValue;
}
}
value = value(prevValue);
}
dispatch(actions.change(form.id, name, value));
},
答案 0 :(得分:2)
我会把
this.props.setFocus(`contacts.${this.props.data.contacts.length-1}.name`);
componentDidUpdate
中的我会在某种情况下调用它。就像让我们说prevProps.data.contact.length < this.props.data.contacts
。
<强>更新强>
你应该保留这个:
addContact = ev => {
ev.preventDefault();
this.props.setField('contacts', contacts => update(contacts, {$push: [{name: 'NEW_CONTACT'}]}));
};
在父组件中,在该组件中,您将呈现所有子组件:
render() {
return {
<div>
{contacts.map(c => <ContactComponent key='blah' contact={c}>)}
<a onClick={addContact}>Add Contact</a>
</div>
};
}
然后您的联系人组件将随意使用,您希望通过此功能容纳的所有其他元素也是如此。
此时,您要问:
焦点在哪里?
这种抽象所需要的是更高阶的构成。我会举一个例子,但请抽出时间阅读有关HOC的内容。
这将是你HOC:
function withAutoFocusOnCreation(WrappedComponent) {
// ...and returns another component...
return class extends React.Component {
componentDidMount() {
// contacts string below can be changed to be handled dynamically according to the wrappedComponent's type
// just keep in mind you have access to all the props of the wrapped component
this.props.setFocus(`contacts.${this.props.data.contacts.length-1}.name`);
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
然后在每个子组件中,您可以将其用作装饰器,或者只需将其与您的HOC一起调用即可。我不会写更多,但确实有时间阅读有关HOC的更多信息,这里是官方文档的页面 official documentation's page。但你也可以查看Dan Abramov关于egghead的视频。我希望我的回答对你有帮助,如果有的话请接受:)照顾好!