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>
    );
  }
}