Reactjs:如何从 submitHandler 访问上下文?
Reactjs: How to Access Context from a submitHandler?
请告诉我我是不是从错误的角度来处理这个问题的。
我有一个 class 组件 App
,它有很多代的子组件。许多孙子组件需要访问 inventory
数据库,因此我选择使用 Context 来存储此数据库。
App
的构造函数的简短摘录:
constructor(props) {
super(props);
this.itemAdd=this.itemAdd.bind(this);
let tempinventory = baseinventory;
//append our itemAdd function to the context
tempinventory.itemAdd = this.itemAdd;
this.state={
inventory:tempinventory,
}
...
}
请注意,我在这里将函数 itemAdd
添加到上下文中,这样孙子们就可以调用此函数,而无需我一直深入研究该回调。
一个孙组件 ItemAddForm
将需要管理一个包含许多字段的表单,并且需要在按下提交按钮时将表单的内容传递到 itemAdd
。我不知道如何实现这一点,因为跟踪表单的内容似乎需要 ItemAddForm
是有状态的 class 组件,但 class 组件无法访问 Context据我所知,在渲染方法之外。
以下是我喜欢的做法:
class ItemAddForm extends React.Component{
constructor(props){
super(props);
this.handleChange=this.handleChange.bind(this);
this.submitHandler=this.submitHandler.bind(this);
this.state = defaultstate;
}
handleChange(event) {
const name = event.target.name;
this.setState({
[name]:value,
});
}
submitHandler(event){
event.preventDefault();
let item=this.state;
this.Context.itemAdd(item);
document.getElementById("InventoryAddForm").reset();
this.setState(defaultstate);
}
render(){
return(
<div>
<form
onSubmit={this.submitHandler}
id="InventoryAddForm"
>
<input
name="price"
className="FormField"
type="text"
onChange={handleChange}
/>
...
</form>
</div>
);
}
}
但显然这不起作用,因为 this.Context 未定义。我真的需要把 ItemAddForm
变成一个纯粹通过钩子监视表单上下文的功能组件吗?我该如何处理?
修改了您的代码以使用上下文消费者模式。 Context 的 Consumer 包装了一个回调,使您可以访问在 Context 的 Provider
中作为 <MyContext.Provider value={/* some value */}>
传递的所有内容
import MyContext from '../my-desired-grandparent-provider';
class ItemAddForm extends React.Component{
constructor(props){
super(props);
this.handleChange=this.handleChange.bind(this);
this.submitHandler=this.submitHandler.bind(this);
this.state = defaultstate;
this.renderContext = null;
}
handleChange(event) {
const name = event.target.name;
this.setState({
[name]:value,
});
}
submitHandler(event){
event.preventDefault();
let item=this.state;
this.renderContext.itemAdd(item);
document.getElementById("InventoryAddForm").reset();
this.setState(defaultstate);
}
renderForm = (value) => (<div>
<form
onSubmit={this.submitHandler}
id="InventoryAddForm"
>
<input
name="price"
className="FormField"
type="text"
onChange={handleChange}
/>
...
</form>
</div>)
render(){
return(
<MyContext.Consumer>
{value => {
this.renderContext = value;
return this.renderForm(value);
}}
</MyContext.Consumer>
);
}
}
请告诉我我是不是从错误的角度来处理这个问题的。
我有一个 class 组件 App
,它有很多代的子组件。许多孙子组件需要访问 inventory
数据库,因此我选择使用 Context 来存储此数据库。
App
的构造函数的简短摘录:
constructor(props) {
super(props);
this.itemAdd=this.itemAdd.bind(this);
let tempinventory = baseinventory;
//append our itemAdd function to the context
tempinventory.itemAdd = this.itemAdd;
this.state={
inventory:tempinventory,
}
...
}
请注意,我在这里将函数 itemAdd
添加到上下文中,这样孙子们就可以调用此函数,而无需我一直深入研究该回调。
一个孙组件 ItemAddForm
将需要管理一个包含许多字段的表单,并且需要在按下提交按钮时将表单的内容传递到 itemAdd
。我不知道如何实现这一点,因为跟踪表单的内容似乎需要 ItemAddForm
是有状态的 class 组件,但 class 组件无法访问 Context据我所知,在渲染方法之外。
以下是我喜欢的做法:
class ItemAddForm extends React.Component{
constructor(props){
super(props);
this.handleChange=this.handleChange.bind(this);
this.submitHandler=this.submitHandler.bind(this);
this.state = defaultstate;
}
handleChange(event) {
const name = event.target.name;
this.setState({
[name]:value,
});
}
submitHandler(event){
event.preventDefault();
let item=this.state;
this.Context.itemAdd(item);
document.getElementById("InventoryAddForm").reset();
this.setState(defaultstate);
}
render(){
return(
<div>
<form
onSubmit={this.submitHandler}
id="InventoryAddForm"
>
<input
name="price"
className="FormField"
type="text"
onChange={handleChange}
/>
...
</form>
</div>
);
}
}
但显然这不起作用,因为 this.Context 未定义。我真的需要把 ItemAddForm
变成一个纯粹通过钩子监视表单上下文的功能组件吗?我该如何处理?
修改了您的代码以使用上下文消费者模式。 Context 的 Consumer 包装了一个回调,使您可以访问在 Context 的 Provider
中作为 <MyContext.Provider value={/* some value */}>
import MyContext from '../my-desired-grandparent-provider';
class ItemAddForm extends React.Component{
constructor(props){
super(props);
this.handleChange=this.handleChange.bind(this);
this.submitHandler=this.submitHandler.bind(this);
this.state = defaultstate;
this.renderContext = null;
}
handleChange(event) {
const name = event.target.name;
this.setState({
[name]:value,
});
}
submitHandler(event){
event.preventDefault();
let item=this.state;
this.renderContext.itemAdd(item);
document.getElementById("InventoryAddForm").reset();
this.setState(defaultstate);
}
renderForm = (value) => (<div>
<form
onSubmit={this.submitHandler}
id="InventoryAddForm"
>
<input
name="price"
className="FormField"
type="text"
onChange={handleChange}
/>
...
</form>
</div>)
render(){
return(
<MyContext.Consumer>
{value => {
this.renderContext = value;
return this.renderForm(value);
}}
</MyContext.Consumer>
);
}
}